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
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"