存在完整错误:“like_post”的反向 未找到参数 '('',)'。尝试了 1 个模式:['recipe/like/(?P[0-9]+)\Z']
我怀疑
post_if
有一些问题,但我无法指出到底出了什么问题。
我真的不知道该怎么办,我想我已经尝试了一切(.
views.py:
def LikeView(request, pk):
post = get_object_or_404(models.Recipe, id=request.POST.get('post_id'))
liked = False
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
liked = False
else:
post.likes.add(request.user)
liked = True
return HttpResponseRedirect(reverse('recipe-detail', args=[str(pk)]))
模板:
{% block content %}
<form action="{% url 'like_post' post.pk %}"
method = "POST">
{% csrf_token %}
<form action="{% url 'like_post' post.pk %}" method="POST">
{% csrf_token %}
{% if user.is_authenticated %}
{% if liked %}
<button type="submit", name="post_id", value="{{ post.id }}", class="btn btn-danger btn-sm">Unlike</button>
{% else %}
<button type="submit", name="post_id", value="{{ post.id }}", class="btn btn-primary btn-sm">Like</button>
{% endif %}
{% else %}
<small><a href="{% url 'login' %}">Login</a> to like</small>
{% endif %}
- {{ total_likes }} Likes
</form>
models.py:
class Recipe(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
ingredients = models.ManyToManyField(Ingredient)
likes = models.ManyToManyField(User, related_name='blog_posts')
def get_absolute_url(self):
return reverse("recipes-detail", kwargs={"pk": self.pk})
def total_likes(self):
return self.likes.count()
def __str__(self):
return self.title
根据错误,模板中很可能没有名为
post
的变量。大概是recipe
。
但是这个模板很奇怪:你在 url 和 POST 参数中都编码了主键,而且你还创建了两个表单,一个嵌套在另一个表单中。
{% block content %}
<form action="{% url 'like_post' recipe.pk %}" method = "POST">
{% csrf_token %}
{% if user.is_authenticated %}
{% if liked %}
<button type="submit" class="btn btn-danger btn-sm">Unlike</button>
{% else %}
<button type="submit" class="btn btn-primary btn-sm">Like</button>
{% endif %}
{% else %}
<small><a href="{% url 'login' %}">Login</a> to like</small>
{% endif %}
- {{ total_likes }} Likes
</form>
我们还可以通过以下方式增强视图:
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
@login_required
def like(request, pk):
liked = False
removed, __ = models.Recipe.likes.through.filter(
recipe_id=pk, user_id=request.user.id
).delete()
if not removed:
models.Recipe.likes.through.create(recipe_id=pk, user_id=request.user.id)
return redirect('recipe-detail', pk)
我们不必先获取
Recipe
项目,而是立即尝试删除与 recipe_id
和 user_id
类似的项目。如果没有记录被删除,我们将继续创建一条记录。
装饰器[Django-doc].@login_required
注意:函数通常用 snake_case 编写,而不是 PascalCase,因此它是 建议将函数重命名为
,而不是like
。LikeView
[Django-doc] 代替 第一次调用redirect(…)
[Django] 和 然后将其包装在reverse(…)
对象[Django-doc]中。HttpResponseRedirect
函数不仅提供了更方便的签名来执行此操作,它还例如将使用redirect(…)
方法[Django-doc] 如果你传递给它一个模型对象。.get_absolute_url()