I recently implemented this functionality in a project. It can be done by using automatically generated uuid's. Django has a built-in model field for this, or you can use a slug field and give it a default value. Here is a quick example.
In your models.py file, import the uuid library and then set the default value of your slug field to be uuid.uuid4.
models.py:
import uuid
class Ticket(models.Model):
uuid = models.SlugField(default=uuid.uuid4, editable=False)
...
In urls.py, just use the uuid field as if it were a pk. Something like this:
url(r'^manager/tickets/(?P<uuid>[0-9a-z-]+)/?$', TicketDetail.as_view(), name='ticket-detail'),
In your detail, update, and delete views, you will need to make sure and set these two attributes so that Django knows which field to use as the slug:
slug_field = 'uuid'
slug_url_kwarg = 'uuid'
Then in your templates and whenever you need to retrieve an object for the kwargs, just use the uuid instead of the pk.
Note that in addition to this, you should also do all you can with permissions to block users from seeing other pages. You may be able to block certain accounts from viewing other peoples details. For instance, you could probably write a permissions mixin to check whether request.user matches up with the object that the view is handling.
tldr This is assuming that you have some kind of relation to a user on your Ticket
model:
class SameUserOnlyMixin(object):
def has_permissions(self):
# Assumes that your Ticket model has a foreign key called user.
return self.get_object().user == self.request.user
def dispatch(self, request, *args, **kwargs):
if not self.has_permissions():
raise Http404('You do not have permission.')
return super(SameUserOnlyMixin, self).dispatch(
request, *args, **kwargs)
Finally, stick it on to your view like this:
class TicketDisplay(LoginRequiredMixin, SameUserOnlyMixin, DetailView):
...