Slug page is not opening

Viewed 42

My slug is coming into the url but the page linked with the page is not opening can anyone please help me with this. I have attached the code please see it and tell me the issue. btw it is a blog page.

Models.py

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.CharField(max_length=100)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(default=timezone.now())
    status = models.IntegerField(choices=STATUS, default=0)

    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title
        
    def get_absolute_url(self):
        return reverse("post_details", kwargs={"slug": self.slug})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            font-family: "Roboto", sans-serif;
            font-size: 18px;
            
        }
    
        .head_text {
            color: white;
        }
    
        
    </style>
</head>
<body>




    {% extends "base.html" %}
    {% block content %}


<header class="masthead">
    <div class="overlay"></div>
    <div class="container">
        <div class="row">
            <div class=" col-md-8 col-md-10 mx-auto">
                <div class="site-heading">
                    <h3 class=" site-heading my-4 mt-3 text-white"> Welcome to my awesome Blog </h3>
                    </p>
                </div>
            </div>
        </div>
    </div>
</header>
<div class="container">
    <div class="row">
        <!-- Blog Entries Column -->
        <div class="col-md-8 mt-3 left">
            {% for post in post_list %}
            <div class="card mb-4">
                <div class="card-body">
                    <h2 class="card-title">{{ post.title }}</h2>
                    <p class="card-text text-muted h6">{{ post.author }} | {{ post.created_on}} </p>
                    <p class="card-text">{{post.content|slice:":200" }}</p>
                    <a href="/blog/{{post.slug}}" class="btn btn-primary">Read More &rarr;</a>

                </div>
            </div>
            {% endfor %}
        </div>
    </div>
</div>
{% endblock content %}

</body>
</html>

post_details.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  {% include 'base.html' %} 

{% block content %}

<div class="container">
  <div class="row">
    <div class="col-md-8 card mb-4  mt-3 left  top">
      <div class="card-body">
        <h1>{% block title %} {{ object.title }} {% endblock title %}</h1>
        <p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
        <p class="card-text ">{{ object.content | safe }}</p>
      </div>
    </div>
  </div>
</div>

{% endblock content %}

</body>
</html>

view.py

def post_Detail(request, slug):
    Post = Post.objects.filter(slug=slug).first()
    context = {'Post': Post}
    return render(request, 'blog/post_details.html')

class PostList(generic.ListView):
    queryset = Post.objects.all().order_by('-created_on')
    template_name = 'index.html'

urls.py

from django.urls import re_path as url

 url('', views.PostList.as_view(), name='home'),
  url('/<str:slug>', views.post_Detail, name='post_Detail'),

here in the url of the server my slug is coming but the template page is not changing it is staying on index page only

1 Answers

First, you must specify the slug field of your model as SlugField (Proper use). If each post is unique, you will have to give the unique parameter to the slug field.

    class Post(models.Model):
    slug = models.SlugField(unique= True)
  
    class Meta:
        ordering = ['-created_on']
  
    def get_absolute_url(self):
        return reverse("post_details", kwargs={"slug": self.slug})

Secondly, post.slug is not a correct usage in template, you should use dynamic url with get_absolute_url.

 <a href="/blog/{{post.get_absolute_url}}"> ...... </a>

instead of

 <a href="/blog/{{post.slug}}"> ...... </a>

Third, You can use get_obejct_or_404 or get instead of using filter.

post = Post.objects.get(slug=slug)

or

from django.shortcuts import get_object_or_404

post= get_object_or_404(Post, slug=slug)

instead of

Post = Post.objects.filter(slug=slug).first()

You don't need to use path separator at the beginning of the URL part. Django does this automatically. But you should also use endings. Also django.conf.urls.url() was deprecated in Django 3.0, and is removed in Django 4.0+. You may want to use path:

from django.urls import path

path('<slug:slug>/', views.post_Detail, name='post_Detail')
Related