Django Slug Field : How To Auto Populate Django Slug

In this tutorial we are going to use django slug field in our url instead of id. Therefore we will implement this in such a way that we will be able to auto populate slug when ever we are typing anything in the title.

What is slugfield in Django.

Slug isa process by which a valid url is generated for an already obtained data .For example, using the title of an article to generate a URL.

Slug is also a unique part of a URL whichidentifies a particular page on a website readable by any user.

Example of django slug.

how-to-create-slug-in-django. Slug doesn’t contain spaces therefore a hiphen or dash is use in spacing. remember if there is no slug our url could have been loke thishow%20to%20use%20slug%20in%20django

In this tutorial our aim would be how to populate slug outside django admin. What I actually mean is that django would be able to use what ever you type in the title as your slug. For example if you are running a public web where every body can post , is either you provide a default one, recall that is not every body would understand what slug is all about. best option for this is to hide the slug field and populate it automatically.

Steps in using django slug field in django and populating it outside django admin

  • Create a django project
  • Create a model and include slug field with instance.
  • Create a view for detail and list view
  • Map a url to the views in views.py
  • Create a template for detail and list view
  • Create a post in form.py for publishing outside django admin

ILLUSTRATION OF HOW TO POPULATING SLUG OUTSIDE DJANGO ADMIN
In this tutorial I assumed that you already know how to create a django project so without wasting much time lets start by creating a model in models.py
We are going to create our model, go to your model.py and include the code below

#models.py

<strong>from</strong> django.db <strong>import</strong> models
<strong>from</strong> datetime <strong>import</strong> datetime
<strong>from</strong> django.urls <strong>import</strong> reverse
<strong>from</strong> django.utils.text <strong>import</strong> slugify



<strong>class</strong> <strong>Article</strong>(models.Model):
    title = models.TextField(null=True,blank=False)
    content = models.TextField(blank=False)
    date_added = models.DateTimeField(default=datetime.now,blank=True)
    slug = models.SlugField(max_length=100,blank=True)

    <strong>def</strong> <strong>__str__</strong>(self):
        <strong>return</strong> self.title

    <strong>def</strong> <strong>get_absolute_url</strong>(self):
        <strong>return</strong> reverse ("article_detail",kwargs={'slug':self.slug})

    <strong>def</strong> <strong>save</strong>(self, *args, **kwargs):  # new
        <strong>if</strong> <strong>not</strong> self.slug:
            self.slug = slugify(self.title)
        <strong>return</strong> super().save(*args, **kwargs)



In the model abovebenchatronics/myapp/models.pywe have created a model and named it Article and added a slug field and use the get absolute url in the instances we also use kwargs and super to override the slug instances.

Now run migrations and migrated so that our intances table would be created.

./manage.py makemigrations

./manage.py migrate

Step2 Go tobenchatronics/myapp/admin.pythen register the models like my own below

You can import a specific model but I like random import so that my code would be simple and dmall

<strong>from</strong> django.contrib <strong>import</strong> admin
<strong>from</strong> . models <strong>import</strong> *


<strong>class</strong> <strong>ArticleAdmin</strong>(admin.ModelAdmin):
    list_display = ('title','date_added',)
    prepopulated_fields = {"slug": ("title","date_added")}

With this prepopulate field whenever you type in your admin the title could be refilling the django slug field as you are typing in the title.

The good thing there is that we can use different name for the title and slug


Now we have to create a view function in our views.py e.g benchatronics/myapp/views.py. Create a view function like the one below


<strong>from</strong> . models <strong>import</strong> *
<strong>from</strong> django.http <strong>import</strong> HttpResponse




<strong>def</strong> <strong>ArticleView</strong>(request):
    article_list = Article.objects.all()
    context = {'article_list':article_list}
    <strong>return</strong> render(request,'article_list.html', context)



Create a url that maps the view in myapp/urls.py

<strong>from</strong> django.urls <strong>import</strong> path
<strong>from</strong> . <strong>import</strong> views


urlpatterns = [
path('blog/',views.ArticleView, name='article_list'),

]



We have to create article_list.html where we can acess our article_list therefore i assumed you know how to configure template. create a template in benchatronics/templates/article_list.html as in my own

This is article_list home
  {% for article in article_list %}
     
  {{article.title}}
   {{article.content}}

  {% endfor %}



We also need to create a detail view for our Article. Now add the code below in your urls.py that means in apps.

urlpatterns = [
    path('/<slug:slug>',views.Article_View,name='article_detail'),
]


after this add this code below in your views.py for mapping the url you have just created above. This views is for Detail_View

# detail view
def Detail_View(request,slug):
        article_detail = Article.objects.filter(slug=slug)

    if article_detail.exists():
        article_detail = article_detail.first()
    else:
        return HttpResponse("<<strong>h3</strong>>Page Not Found otherwise contact us</<strong>h3</strong>>")

    context = {'article_detail':article_detail}
    return render(request,'article_detail.html', context)

Now we are ready to check our instances in admin. head over to your admin then start to create an Article you will see that as you type in the title it will be populating in the slug. but i have just created all these because i want to show you guys this in outside admin.

Now create a python file in myapp, name it form.py then add this code below

benchatronics/myapp/form.py

from .models <strong>import</strong> *
from django <strong>import</strong> forms
from django.contrib.auth.models <strong>import</strong> User


  <strong>class</strong> <strong>ArticleForm</strong>(forms.ModelForm):
    <strong>class</strong> <strong>Meta</strong>:
        model = Article
        fields = ('title','content','date_added',)
        widgets = {
            'title': forms.TextInput(attrs={'class':'form-control'}),
            'content': forms.TextInput(attrs={'class':'form-control'}),
            
            'date_added': forms.TextInput(attrs={'class':'form-control'}),
            'slug': forms.TextInput(attrs={'class':'form-control'}),
        }

      

Django Gmail – How To Send Email In Django

After creating form.py we will need to create a view function then map the required url for posting outside django admin

go to views.py and add these codes below.


<strong>from</strong> . forms <strong>import</strong> *
<strong>from</strong> . models <strong>import</strong> *
<strong>from</strong> django.http <strong>import</strong> HttpResponse
<strong>from</strong> django.shortcuts <strong>import</strong> render,get_object_or_404

#health post
<strong>def</strong> <strong>Post_View</strong>(request):
    # dictionary for initial data with
    # field names as keys
    context ={}

    # pass the object as instance in form
    form= PostForm(request.POST <strong>or</strong> None)

    # save the data from the form and
    # redirect to detail_view
    <strong>if</strong> form.is_valid():
        form.save()
        <strong>return</strong> redirect('index')

    # add form dictionary to context
    context= {'form':form}

    <strong>return</strong> render(request, "add_article.html", context)

go to myapp/urls.py and map the url accordingly

<strong>from</strong> django.urls <strong>import</strong> path
<strong>from</strong> . <strong>import</strong> views





urlpatterns = [
        path('add_article',view.Post_View,name="add_article"),
]

Then we have to create an add_article.html so that we can be able to access the page.

go to templates then create html file
templates/add_article.html

<form method="post">

    <div <strong>class</strong>="m-2 container ">
    {% csrf_token %}
    
    {{form.as_p}}
    <button <strong>class</strong>="btn btn-primary" type="submit" >Post</button>
    </div>
</form>

Then save it and refresh server by running /manage.py runserver. you can access the add_article at localhost:8000/add_article or you can add it to your homepage navbar as in<a href="{% url 'add_article' %}>Add post</a>

Your slug is now automatically populated, I have set slug to blank= True because we won't be typing slug all the time except you want to type it your self.

Another way to do this If you want users to post on your site then slug must be prepolated, you can set title to recieve a max_length of 100 and slug a max_length of 100 too then edit your add_article forms.py to be like this.

<strong>from</strong> .models <strong>import</strong> *
<strong>from</strong> django <strong>import</strong> forms
<strong>from</strong> django.contrib.auth.models <strong>import</strong> User


  <strong>class</strong> <strong>ArticleForm</strong>(forms.ModelForm):
    <strong>class</strong> <strong>Meta</strong>:
        model = Article
        fields = ('title','content','date_added',)
        widgets = {
            'title': forms.TextInput(attrs={'class':'form-control'}),
            'content': forms.TextInput(attrs={'class':'form-control'}),
            
            'date_added': forms.TextInput(attrs={'class':'form-control'}),
            'slug': forms.TextInput(attrs={'class':'form-control','type':'hidden',}),
        }

One thought on “Django Slug Field : How To Auto Populate Django Slug

Leave a Reply

Your email address will not be published. Required fields are marked *