26. Creation of slugs for dynamic URLs
We will utilize slugs to prevent issues related to URL formatting and encoding. Slugs enable the admin to enforce URL rules, such as prohibiting spaces and special characters. To implement this, we will update the Category
and Type
classes by adding a slug
attribute.
class Categoric(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
slug = models.CharField(max_length=200, null=True, blank=True)
def __str__(self) :
return str(self.name)
class Type(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
slug = models.CharField(max_length=200, null=True, blank=True)
def __str__(self) :
return str(self.name)
Note: As previously done in Chapter 5.3, when making direct changes to our database models, we need to perform migrations to apply these changes.
python manage.py makemigrations
python manage.py mmigrate
Navigate to each category and type within the administrative interface. Format their names in uppercase, remove spaces, and exclude special characters when entering them into the slug field.

Now, we need to update the code segments that were directly accessing information from unformatted names to use slugs instead. We'll start by changing the href
URLs in navbar.html
from category.name
and type.name
to category.slug
and type.slug
, respectively.
<div style="display: flex;">
{% for category in categories %}
<div>
<a href="{% url 'store' %}{{ category.slug }}">{{ category.name }}</a>
<br>
{% for type in types %}
<a href="{% url 'store' %}{{ category.slug }}-{{ type.slug }}">{{ type.name }}</a>
{% endfor %}
</div>
{% endfor %}
</div>
Lastly, we need to update the store
view function. Previously, it filtered products by their category name. The updated code segment should now filter products using products.filter(category__slug=category_name)
.
For organizational purposes, we will also change all iteration names of category_name
to filter
.
def store(request, filter = None):
products = Product.objects.filter(active=True) #? grabbing all products from the database (queryset, result of the search of the database)
if filter:
products = products.filter(category__slug = filter) #? gets the slug atribute from the category class and filters it according to the name of the category obtained from the banner
context = {"products" : products}
return render(request, 'store.html', context)
We also need to update the parameter name in urls.py
from str:category_name
to str:filter
path('store/<str:filter>/', store, name="store"), #? comes after the fixed urls, allows to create multiple urls with varied names
Last updated