1👍
- If id is unique then why slug?
Slug is just a way for you to quickly get a sense of what this URL is about – the readability of it which is not guaranteed by only using id
.
- If its important then should we store it?
URL of this question could be Should I use slug field too in django URLs? and still it redirects to same post. But having said that it also depends on the implementation. In this case it could be that Stack Overflow checks for a valid slug corresponding to the post ID and if not found then redirects to the original one.
I just changed the title of the question and as a result the URL changed as well:
old => http://stackoverflow.com/questions/42407755/should-i-use-slug-field-too-in-django
new => http://stackoverflow.com/questions/42407755/should-i-use-slug-field-too-in-django-urls
So if you store the slug you need to make sure it is updated everytime title is changed.
- If it has anything to do with
canonical-link
please elaborate the working of canonical links & how slug can help it?
Canonical links are used by Search Engines to identify duplicate URLs which lead to same content. YOu can view to source code of this post and you can find following canonical link in the HEAD:
<link rel="canonical" href="http://stackoverflow.com/questions/42407755/should-i-use-slug-field-too-in-django-urls">
A search engine will collect this URL and return it to you when you search for some keywords which matches this URL. One of the factors based on which the search engine ranks the pages is matching keywords in URL. A good slug helps the search engine to return the user best results based on the matched keywords in the URL.
0👍
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.
- Django Migrate Fails due to Type Conflict
- Django user registration where username becomes "firstname.lastname"