Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use slugs in django url

Tags:

django

Have been scared to ask this here, just started with Stack Overflow and, believe me, I have tried searching for this question, but mostly I saw regex patterns.

Please if anyone could be kind enough to guide me through these few issues:

  1. How to fill my blog model slug field automatically with the post name without filling it up myself.

  2. How to make a link to go to the single post page using the slug WITHOUT regex in Django 2.x

Thanks.

like image 540
Cole Avatar asked Oct 30 '18 14:10

Cole


People also ask

What is slug in URL Django?

A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They're generally used in URLs." To give a concrete example, assume you had a Newspaper website (such as we'll build in this tutorial).

Why slug is used in Django?

Slug is a part of a URL which identifies a particular page on a website in a form readable by users. For making it work django offers us a slugfield. It can be implimented as under. We already had a model Article we will be adding slugfield to it to make it user readable.

What is the slug of a URL?

A slug is the part of a URL that identifies a particular page on a website in an easy-to-read form. In other words, it's the part of the URL that explains the page's content. For this article, for example, the URL is https://yoast.com/slug, and the slug simply is 'slug'.

How do I configure slug based routing in Django?

Now we want to configure slug based routing in Django. To design URLs for an app, we learned how to use the Python module URLconf or URL configuration. The URLconfg uses Python code to map between URL path expressions and Python functions that are defined in views. Some routing paths are static, and some are dynamic.

How to make URLs Pretty in Django?

In order to make URLs pretty in Django, we can use slug based routing. Using slugs also provides SEO benefits as search engines will understand a descriptive slug better than a simple ID in the URL. In this tutorial we learned how to handle using a slug for routing, querying the database, and rendering a template for a post detail page.

What is a slug in Django?

the thing is that i am following a youtube course , and he is using an older version of Django. @MarioRojas: but then it is a str, and a str can for example contain spaces, characters with diacritics, etc. A slug is exactly defined to make URL parameters look "pretty").

What is a slug in HTML?

A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs.". To give a concrete example, assume you had a Newspaper website (such as we'll build in this tutorial). For a story titled "Hello World," the URL would be example.com/hello-world assuming the site was called example.com.


1 Answers

So you haven't posted your code, but assuming your model looks like this:

class Post(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    content = models.TextField()

And that you want to pre-fill the slug from the title, you have a few options depending on where you want to do it:

  1. Post will be created only by staff users: pre-populate it in the admin
  2. Post will be created outside of the admin: override .save() method

From the admin

The easiest way to get this in the admin is via the prepopulated_fields

@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}

Django will auto-update the slug field as you type the title when creating a post. Very nice UX, but limited to the admin...

Outside of the admin

In the previous example, you might end up with an empty slug if you were to create a post from the console, or from another page. In this case, you can quickly make sure slug is prepopulated by overriding the model's .save() method, and calling slugify in it:

class Post(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    content = models.TextField()

    def save(self, *args, **kwargs):
        self.slug = self.slug or slugify(self.title)
        super().save(*args, **kwargs)

Link Post by slug

Disclaimer: if you need more details on this part, I suggest the part 3 of the official tutorial.

Provided you have a URL path:

# urls.py
from django.urls import path
from your_blog import views

urlpatterns = [
    path('posts/<slug:the_slug>/', views.post_detail_view, name='show_post'),
]

Then, in your views module you have a view:

# your_blog/views.py 
from django.views.generic.detail import DetailView


class PostDetailView(DetailView):
    model = Post
    # This file should exist somewhere to render your page
    template_name = 'your_blog/show_post.html'
    # Should match the value after ':' from url <slug:the_slug>
    slug_url_kwarg = 'the_slug'
    # Should match the name of the slug field on the model 
    slug_field = 'slug' # DetailView's default value: optional

post_detail_view = PostDetailView.as_view()

You can link to a Post by calling, in Python:

reverse('show_post', args=[the_post.slug])

Or in a Django template:

<a href="{% url 'show_post' the_post.slug %}">{{ the_post.title }}</a>

EDIT: Post index page

You could then add an index page, generating a list linking to all your posts:

# your_blog/views.py 
from django.views.generic import ListView


class PostListView(ListView):
    model = Post
    # This file should exist somewhere to render your page
    template_name = 'your_blog/list_post.html'

And in the view template:

<!-- your_blog/list_post.html -->
<ul>
  {% for the_post in object_list %}
    <li>
      <a href="{% url 'show_post' the_post.slug %}">{{ the_post.title }}</a>
    </li>
  {% endfor %}
</ul>

Hope that helps :)

like image 182
Bruno A. Avatar answered Sep 28 '22 03:09

Bruno A.