Django: NameError: Slug Is Not Defined
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
class HomeFeedView(ListView):
model = Post
template_name "HomeFeed/snippets/home.html"
context_object_name = "blog_posts"
ordering = ("-date_updated",)
class LikeView(View):
def dispatch(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.
return super().dispatch(request, *args, **kwargs)
def get(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}))
class PostDetailView(DetailView):
model = Post
template_name = "HomeFeed/detail_blog.html"
context_object_name = "blog_post"
slug_url_kwarg = "post_slug"
slug_field = "slug"
def get_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-->
<a href="{% url 'HomeFeed:post_detail' post.slug %}">View Post</a>
<a href="{% 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
def home_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 = False
if 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"