Search code examples
djangoprimary-keydjango-urlsidentifier

Hide primary keys or ids from being exposed


Currently while adding, editing or deleting a object i am using the id (pk) of the object in the urls which of course exposes the global primary key id of that particular object to the users. I somehow want to hide those global id's from the urls and/or from the hidden fields within a form while using POST.

Just to make it a little more clear let me explain this with an example. So say i have the following models.

Models.py

class Profile(User)
    # Some fields here


class Student(Profile)
    # some fields here


class Teacher(Profile)
    # Some fields here


class Project(models.Model)
    student = models.ForeignKey(Student)
    # some more fields here.

according to the above models, say i want to either edit or delete an existing Project instance. what I currently do is use the id(pk) as an argument in the urls as follows:

Urls.py

url(r'^project/(?P<id>\d+)/edit/$', 'app.views.edit_project'),
url(r'^project/(?P<id>\d+)/delete/$', 'app.views.delete_project'),

what would be the best approach to either completely hide these id's from the url?

is there a way we could have Project Id's per student ? something like adding another auto_increment column to the Project table ?


Solution

  • The SlugField() option proposed by Antony is a great idea. Put a unique constraint on the field (unique=True in your model definition). Then write your urls.py rules like this:

    url(r'^project/(?P<slug>[A-Za-z0-9_\-]+)/edit/$', 'app.views.edit_project'),
    url(r'^project/(?P<slug>[A-Za-z0-9_\-]+)/delete/$', 'app.views.delete_project'),