Home > Enterprise >  pk argument on Django blog
pk argument on Django blog

Time:01-04

I'm working on a blog and I was following instructions but now I don't understand why I have problem with pk.

This is my views.py

from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import Category, Post

def post_list(request):
    posts =  Post.objects.filter(created_at__lte=timezone.now()).order_by('created_at')
    latest_posts =  Post.objects.filter(created_at__lte=timezone.now()).order_by('created_at')[:9]

    context = {'posts': posts, 'latest_posts': latest_posts}
    return render(request, 'home.html', context)

def post_detail(request, post, pk):
    latest_posts =  Post.objects.filter(created_at__lte=timezone.now()).order_by('created_at')[:9]
    post = get_object_or_404(Post, pk=pk)

    context = {'post': post, 'latest_posts': latest_posts}
    return render(request, 'post_detail.html', context)

This is blog/urls.py

urlpatterns = [
    path('', views.post_list, name='home'),
    path('<slug:post>/', views.post_detail,  name='post_detail'),
]

This is models.py

class Post(models.Model):
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
    is_published = models.BooleanField(default=False, verbose_name="Is published?")
    published_at = models.DateTimeField(null=True, blank=True, editable=False, verbose_name="Published at")
    title = models.CharField(max_length=200, verbose_name="Title")
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey('auth.User', verbose_name="Author", on_delete=models.CASCADE)
    category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE)
    body = RichTextField(blank=True, null=True)
    image = StdImageField(upload_to='featured_image/%Y/%m/%d/', variations={'standard':(1170,820),'banner':(1170,530),'thumbnail':(500,500)})
    status = models.IntegerField(choices=STATUS, default=0)

    def get_absolute_url(self):
        return reverse('post_detail', args=[self.slug])

    class Meta:
        verbose_name = "Post"
        verbose_name_plural = "Posts"
        ordering = ['-created_at']

    def publish(self):
        self.is_published = True
        self.published_at = timezone.now()
        self.save()

    def __str__(self):
        return self.title

Also, I'm adding a list of post, it might be connected with get_absolute_url


{% extends "base.html" %}
{% load static %} 
    {% block content %}
    <!-- Main Wrap Start -->
    <main >
        <div >
            {% for post in latest_posts %}
            <div >
                <div >
                    <div >
                        <!--<span ><i ></i></span>-->
                        <a href="{{ post.get_absolute_url }}">
                            <img  src="{{ post.image.standard.url }}" alt="post-slider">
                        </a>
                    </div>
                    <h6 >
                        <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
                    </h6>
                    <div >
                        <span >By <a href="#">{{ post.author }}</a></span>
                        <span >{{ post.created_at}}</span>
                    </div>
                </div>
            </div>
            {% endfor %}
        </div>
    </main>
    {% endblock content%}

I have an error...

post_detail() missing 1 required positional argument: 'pk'

Everything was working until I was started working on post detail. Any ideas why this is happening?

CodePudding user response:

You seem to be confused with what the primary key for your model is. The primary key is the auto-generated id (pk) but according to your urls.py you want to use slug for fetching records.

First, change your path to:

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

then your view signature to:

def post_detail(request, slug):

and finally, fetch your record using:

post = get_object_or_404(Post, slug=slug)
  • Related