DEV Community

DoriDoro
DoriDoro

Posted on

How to creating a SEO friendly URL in a Django project

Introduction

By creating an Search engine optimization (SEO) friendly URL, you will structure the pattern of a URL in a more meaningful way and make it easier for your content to be indexed.

To avoid a URL like www.example.com/blog/1/, create a canonical URL (get_absolute_url()) in the models.py file and we can change the URL pattern of the canonical URL to a SEO friendly URL.


Here is the Post model:

# models.py

from django.db import models
from django.urls import reverse

class Post(models.Model):
    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250)
    author = models.ForeignKey(
        "account.User", on_delete=models.CASCADE, related_name="blog_posts"
    )
    body = models.TextField()

    def __str__(self):
        return self.title
Enter fullscreen mode Exit fullscreen mode

This code is a function-based view (FBV) to display one single Post instance on the website:

# views.py

from django.shortcuts import render, get_object_or_404

from blog.models import Post

def post_detail(request, pk):
    post = get_object_or_404(
        Post,
        pk=pk
    )
    return render(request, "post/detail.html", {"post": post})
Enter fullscreen mode Exit fullscreen mode

And the url pattern for the view:

# urls.py

from django.urls import path

from blog import views

urlpatterns = [
    path('<int:pk>/', views.post_detail, name='post_detail')
]
Enter fullscreen mode Exit fullscreen mode

Now we create the get_absolute_url() method in the Post model. We will use the model attribute slug to generate the SEO friendly URL. The URL pattern will change from www.example.com/blog/pk/ (www.example.com/blog/1/) (1 is the pk (id) of the post instance) and the new URL will look like: www.example.com/blog/slug/ (www.example.com/blog/name-of-the-post/).

# models.py

from django.db import models
from django.urls import reverse

class Post(models.Model):
    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250, unique_for_date="publish")
    author = models.ForeignKey(
        "account.User", on_delete=models.CASCADE, related_name="blog_posts"
    )
    body = models.TextField()

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse(
            "blog:post_detail",
            args=[self.slug],
        )
Enter fullscreen mode Exit fullscreen mode

The get_absolute_url() method in Django is used to define the canonical URL for a model object, making it easier to refer to specific objects in templates or views. It returns the absolute URL path as a string, which can be used for redirection or linking. We often use the reverse() function inside get_absolute_url() because it resolves the URL based on the view name and arguments, ensuring a reliable and maintainable URL pattern that adapts to changes in the project’s URL configuration.

Now, we update the view, to exchange the pk with the slug:

# views.py

from django.shortcuts import render, get_object_or_404

from blog.models import Post

def post_detail(request, slug):
    post = get_object_or_404(
        Post,
        slug=post
    )
    return render(request, "post/detail.html", {"post": post})
Enter fullscreen mode Exit fullscreen mode

Don't forget to update the url pattern, and pass the slug as an argument:

# urls.py

from django.urls import path

from blog import views

urlpatterns = [
    path('<slug:post>/', views.post_detail, name='post_detail')
]
Enter fullscreen mode Exit fullscreen mode

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs