Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i use slug urls correctly in Django?

Hello, i'm new to Django, and I'm trying to build a web site. at the admin page http://127.0.0.1:8000/admin/posts/post/ i added two posts, eatch one have a slug, the **first slug is first and the second one is second the problem is when i try to reach http://127.0.0.1:8000/posts/first or http://127.0.0.1:8000/posts/second it gives me a 404 error and it tells me**

Using the URLconf defined in custom.urls, Django tried these URL patterns, in this order:

admin/
posts/ [name='posts_list']
<slug>

The current path, posts/first, didn't match any of these.

this is models.py

from django.db import models
from django.conf import settings
Create your models here.

User = settings.AUTH_USER_MODEL

class Author(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    email = models.EmailField()
    phone_num = models.IntegerField(("Phone number"))

    def __str__(self):
       return self.user.username

class Post(models.Model):
    title = models.CharField(max_length=120)
    description = models.TextField()
    slug = models.SlugField()
    image = models.ImageField()
    author = models.OneToOneField(Author, on_delete=models.CASCADE)


    def __str__(self):
        return self.title

this is views.py

from django.shortcuts import render, get_object_or_404
from .models import Post
# Create your views here.


def posts_list(request):
    all_posts = Post.objects.all()
    return render(request, 
                  "posts/posts_list.html", 
                  context = {"all_posts": all_posts})


def posts_detail(request, slug):
    unique_slug = get_object_or_404(Post, slug = slug)

    return render(request, "posts/posts_detail.html", {"post": unique_slug})

this is the urls.py

from django.contrib import admin
from django.urls import path
from posts.views import posts_list, posts_detail
urlpatterns = [
        path('admin/', admin.site.urls),
        path("posts/", posts_list, name = "posts_list"),
        path("<slug>", posts_detail), #, name = "unique_slug"
    ]

and this is those are the templates: posts_list.html

<!DOCTYPE html>
<html>
    <head>
        <title>
        </title>
    </head>
    <body>
        {{ all_posts }}
    </body>
</html>

post_detail.html

<!DOCTYPE html>
<html>
    <head>
        <title>
        </title>
    </head>
    <body>
        {{ post }}
    </body>
</html>
like image 297
Abbas Med Avatar asked Dec 13 '22 09:12

Abbas Med


2 Answers

A slug never contains a slash. It looks like your url is prefixed with posts/. So you can alter your urls.py with:

from django.contrib import admin
from django.urls import path
from posts.views import posts_list, posts_detail

urlpatterns = [
    path('admin/', admin.site.urls),
    path('posts/', posts_list, name='posts_list'),
    path('posts/<slug:slug>/', posts_detail, name='unique_slug'),
]

It is probably better to add the type of the path converter, so <slug:slug>.

You might want to use django-autoslug [GitHub] to automatically construct a slug based on a certain field.

like image 74
Willem Van Onsem Avatar answered Dec 28 '22 01:12

Willem Van Onsem


You have made two mistakes here first>>>

#you havent closed the last bracket and with comma

path("<slug>", posts_detail), #, name = "unique_slug"__<<

The second mistake you made is that you havent defined the slug type which is an important point

like image 22
Kartikey Srivastava Avatar answered Dec 28 '22 03:12

Kartikey Srivastava