Package: proxyid
ProxyidProxyid hides your Django model primary keyProxyid turnshttps://myapp.com/model/1intohttps://myapp.com/model/5NxJD1dG6VIt makes use of thehashids libraryto mask your integer or uuid based primary keys. It's plug'n play, therefore, it doesn't interfere with the database or model definitions.TypePrimary KeyExposed Proxied PKInteger35NxJD1dG6VB3ZR3eKyzYEWrbaUUID82df2e8e-553b-4330-bd46-8299ec67a9bb7ljjRD1qVLfjkQepdRZAimyDDZZ2Quick StartAssuming a Django project is already set with an app called appmock, proxyid can be installed withpip.$ pip install proxyidThe configuration is set as a constantPROXYIDinsettings.pyPROXYID={"hashids":{"salt":"A grain of salt",# this is your salt"min_length":15# this is the minimum length of the proxied id}}Let's say the project has an Author model# djangoproject/appmock/models.pyfromdjango.dbimportmodelsclassAuthor(models.Model):name=models.CharField()nationality=models.CharField()def__str__(self):returnself.nameNow take a look at oururls.py# djangoproject/appmock/urls.pyfromdjango.urlsimportpathfromappmockimportviewsurlpatterns=[# ...other path configuration# ...other path configuration# ...other path configurationpath("author/<pk>/",views.author_detail,name="author-detail")]Proxify the Primary KeyIf the app is exposing the database's primary key, the Author resource would be found, for example, athttp://myapp.com/author/1Let's hide our primary key. by importing theproxifydecorator and defining a property method.# djangoproject/appmock/models.pyfromdjango.dbimportmodelsfromproxyid.decoratorsimportproxifyclassAuthor(models.Model):name=models.CharField()nationality=models.CharField()@property@proxifydefid_(self):passdef__str__(self):returnself.nameThat's it, now our model instance will have theid_property with it's unique primary key encoded by proxyid by using the hashids library. All we need  is a method which doesn't return anything and the decorators@propertyand@proxify. You can name this property method whatever you want(exceptpkorid), let's name itid_for this example.Let's check it by retrieving a model in a django shell session$ python manage.py shell
Python 3.9.2 (default, Mar 21 2021, 20:35:03)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from appmock import models
>>> author = models.Author.object.create(name="Lima Barreto", nationality="Brazil")
>>> author.id
1
>>> author.id_
RvBykxK6qojOJnOMrQeGpALDWRetrieving objects from encoded Primary KeysNow, how about retrieving our object from the database if our user is giving us the encoded(RvBykxK6qojOJnOMrQeGpALDW) primary key?
Let's go to our hypotheticalauthor_detailview function inviews.py# djangoprojects/appmock/views.pyfromdjango.shortcutsimportrender,HttpResponsefromappmock.modelsimportAuthorfromproxyid.encodingimportdecode# ...other codedefauthor_detail(request,pk):decoded_pk=decode(pk)# this will bring RvBykxK6qojOJnOMrQeGpALDW back to 1author=Author.objects.get(pk=decoded_pk)context={"author":author}returnrender(request,"appmock/author_detail.html",context)We importeddecodefromproxyid.encoding, thedecodefunction will transform our proxied value back to it's original primary key value, allowing us to retrieve our object by giving the pk value to the ORM.How the urls were generated? By just passing the objectid_instead ofpkproperty or whatever name you have it to the url function. Like this:<!-- some html -->

{% url 'author-detail' author.id_ %}Now our author resource can be found athttp:myapp.com/author/RvBykxK6qojOJnOMrQeGpALDWWhat about class based views?Let's build the same logic ofauthor_detailfunction view as a class based view now:# djangoproject/appmock/views.pyfromdjango.viewsimportgenericfromappmock.modelsimportAuthorfromproxyid.mixinsimportProxyidMixinclassAuthorDetailView(ProxyidMixin,generic.DetailView):template_name="appmock/author_detail.html"model=Authorcontext_object_name="author"That's it, the view will work the same way as long as you use theProxyidMixinas a parent class, and don't forget to provide apkargument(this can be customized) from the url dispatcher.