You need to identify a post by exactly 1 unique identifier. That can be either the ID or the slug. Using both is pointless and prone to errors. You can include both a slug and an id in the title, in which case you should probably just ignore the slug entirely passed in the URL and use the ID.
You can ignore the slug and just use the ID like this:
url(r'^(?:[\w-]+)/(?<id>\d+)/$', BlogView.as_view(), name='blog-view')
If you do that you don't need to store the slug at all, just generate it from the title each time you use it.
Personally, I prefer slugs because they provide friendlier URLs which integrate well with Django. For example with a class based view you can create a URL that looks like this:
url(r'^(?P<slug>[\w-]+)/$', BlogView.as_view(), name='blog-view')
And your class based view is super clean:
class BlogView(DetailView):
model=BlogEntry
That's it! Django automagically knows to look the model up by the slug and assuming you have your template named properly you don't need to wire anything else up (Ok you probably do). There is a really helpful gist on github about this setup.
If you want to use slugs, generate it when you save the record and use some kind of automatic mangling to make it unique if there is a collision (or let the user manually override it). In one of my blogs I incorporate the date in the slug to make it more unique then use a recursive function to ensure it's unique. (here's an little tutorial someone made on making unique slugs). It is a good idea to include some way to manually over-ride the slug also.
In the above link he uses a for loop, personally I prefer a recursive function such as:
def autoslug(self, slug, attempt=1):
if MyModel.objects.filter(slug=slug).exists():
return autoslug(slug[:47]+"%d" % attempt, attempt + 1)
else:
return slug
You create a slug field on the model to store the slug. For example, Class Based views can pass a slug and it will magically figure out what you want. Django's has a variety of internal tools that reference it by that name so keep it simple and use the same name django expects.
Also, the URL for a given resource should be unchanging so links are persistent. Changing a slug when you change the title means the URL for the resource changes, IMO it's always a bad idea for the same resource to have a changing URL. It's bad for SEO and bad for anyone who links your resources externally.