Loading lesson path
Concept visual
Start at both ends
Have you ever seen url's that look like this:
Formula
w3schools.com/django/learn - about - slug - fieldThe "
Formula
learn - about - slug - field" part is a slug. It is a description containing only letters, hyphens, numbers or underscores. It is often used in url's to make them easier to read, but also to make them more search engine friendly.
Django Project created in this tutorial, you will have a small Django project looking like this: And if you click the first member, you will jump to this page:
Formula
127.0.0.1:8000/members/details/1The number "1" refers to the ID of that particular record in the database.
Makes sense to the developer, but probably not to anyone else.It would have made more sense if the url looked like this:
Formula
127.0.0.1:8000/members/details/emil - refsnesThat is a more user friendly url, and Django can help you create such url's in your project. Modify the models.py File Start by adding a new field in the database. Open the models.py file and add a field called slug with the data type
Formula
my_tennis_club/members/models.pyfrom django.db import models
class Member(models.Model):
Formula
firstname = models.CharField(max_length = 255)
lastname = models.CharField(max_length = 255)
phone = models.IntegerField(null = True)
joined_date = models.DateField(null = True)
slug = models.SlugField(default ="", null = False)def __str__(self):
return f"{self.firstname} {self.lastname}"
This is a change in the Model's structure, and therefor we have to make a migration to tell Django that it has to update the database:python manage.py makemigrations
python manage.py migrate
Now we have a new field in the database, but we also want this field to be updated automatically when we set the firstname or lastname of a member. This can be done with a built-in Django feature called prepopulated_fields where you specify the field you want to pre-populate, and a tuple with the field(s) you want to populate it with. This is done in the admin.py file:
Formula
my_tennis_club/members/admin.pyfrom django.contrib import admin from .models import Member
# Register your models here.
class MemberAdmin(admin.ModelAdmin):
Formula
list_display = ("firstname", "lastname", "joined_date",)prepopulated_fields = {"slug": ("firstname", "lastname")}admin.site.register(Member, MemberAdmin) Enter the Admin interface and open a record for editing: Click "SAVE" and the "slug" field will be auto populated with the firstname and the lastname, and since the "slug" field is of type SlugField, it will "slugify" the value, meaning it will put a hyphen between each word. Next time you open the member for editing you will see the slug field with value:
Since the new field is empty by default, you have to do this save operation for each member.
Now we can replace the ID field with the slug field throughout the project. Start with the all_members.html template, where we have a link to the details page:
Formula
my_tennis_club/members/templates/all_members.html{% extends "master.html" %}{% block title %}Formula
My Tennis Club - List of all members{% endblock %}{% block content %}
<div class="mycard">Formula
< h1 > Members </h1 ><ul>
{% for x in mymembers %}
<li onclick="window.location = 'details/'"> </li>
{% endfor %}</ul> </div>
{% endblock %}We also have to make some changes in the urls.py file.
<int:id> to <slug:slug>
Formula
my_tennis_club/members/urls.pyfrom django.urls import path from . import views
urlpatterns = [ path('', views.main, name='main'), path('members/', views.members, name='members'), path('members/details/<slug:slug>', views.details, name='details'), path('testing/', views.testing, name='testing'), ]
Finally, change the details view to handle incoming request as slug instead of ID:
Formula
my_tennis_club/members/views.pyfrom django.http import HttpResponse from django.template import loader from .models import Member
def members(request):Formula
mymembers = Member.objects.all().values()
template = loader.get_template('all_members.html')context = {
'mymembers': mymembers,
}
return HttpResponse(template.render(context, request))def details(request, slug):Formula
mymember = Member.objects.get(slug = slug)
template = loader.get_template('details.html')context = {
'mymember': mymember,
}
return HttpResponse(template.render(context, request))def main(request):Formula
template = loader.get_template('main.html')return HttpResponse(template.render())def testing(request):Formula
template = loader.get_template('template.html')context = {
'fruits': ['Apple', 'Banana', 'Cherry'],
}
return HttpResponse(template.render(context, request))Now the link to details works with the new slugified url: If you have followed all the steps on your own computer, you can see the result in your own browser:
Formula
127.0.0.1:8000/members/.
If the server is down, you have to start it again with the runserver command:python manage.py runserver