Skip to content Skip to sidebar Skip to footer

Django: Nameerror: Slug Is Not Defined

Can anyone advise on how to query the `total_likes of a post to be shown in my HTML, I tried, but was given this error: NameError: Slug is not defined An expert has suggested me t

Solution 1:

I will give you a solution that uses class based views, to show you how clearer they are (no boilerplate code)

urls.py

from .views import LikeView, PostDetailView, HomeFeedView

urlpatterns = [
    ...
    path("home/", HomeFeedView.as_view(), name="home"),
    path("like-post/<str:post_slug>/", LikeView.as_view(), name="like_post"),
    path("post-detail/<str:post_slug>/", PostDetailView.as_view(), name="post_detail"),
]

Then in your views.py

from django.views import View
from django.views.generic import DetailView, ListView
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect


classHomeFeedView(ListView):
    model = Post
    template_name "HomeFeed/snippets/home.html"
    context_object_name = "blog_posts"
    ordering = ("-date_updated",)


classLikeView(View):

    defdispatch(self, request, *args, **kwargs):
        self.post = get_object_or_404(Post, slug=kwargs["post_slug"])
        # If you get a 404 error here, then your `slug` is not valid.returnsuper().dispatch(request, *args, **kwargs)

    defget(self, request, *args, **kwargs):
        if self.post.likes.filter(id=request.user.id).exists():
            self.post.likes.remove(request.user)
        else:
            self.post.likes.add(request.user)
        return HttpResponseRedirect(reverse_lazy("HomeFeed:post_detail", kwargs={"post_slug": self.post.slug}))

classPostDetailView(DetailView):
    model = Post
    template_name = "HomeFeed/detail_blog.html"
    context_object_name = "blog_post"
    slug_url_kwarg = "post_slug"
    slug_field = "slug"defget_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        post = self.object
        context.update({
            "total_likes": post.total_likes,
            "liked": self.request.user in post.likes.all(),
        })
        return context

And to factor in the change(s) in your HTML snippet:

<!-- Template -->

{% for post in blog_posts %}
    <!-- Other markup--><ahref="{% url 'HomeFeed:post_detail' post.slug %}">View Post</a><ahref="{% url 'HomeFeed:like_post' post.slug %}">Like Post</a><!-- Other markup -->
{% endfor %}

Then to show total likes etc, only do that in your template(s). For checking if user liked a certain post, use templatetags/filters that will enable you to say for example, while looping:

{% with post|liked_by:user as liked %}
    <!-- 'liked' will be a bool, then do whatever you want with it.
{% endwith %}

This is one way to do it, but not the best way. You might also need to look that up (whether user liked post or not) using annotations on the queryset so that all the logic(especially the kind that involves a queries to the database) is handled at view level, not inside templates.

Solution 2:

The problem is home_feed_view isn't designed to take another parameter("slug")

You could have(based on your form's action attribute):

views.py

defhome_feed_view(request, slug=None):
    
    context = {}
    ...
    if slug:
        blog_post = get_object_or_404(BlogPost, slug=slug)
        ## add blogpost to content only if it exists
        context['blog_post'] = blog_post
        total_likes = blog_post.total_likes()
        liked = Falseif blog_post.likes.filter(id=request.user.id).exists():
            liked = True
        context['total_likes'] = total_likes

    ...

Post a Comment for "Django: Nameerror: Slug Is Not Defined"