django.urls.exceptions.NoReverseMatch:找不到参数 '('',)' 的反向 'like_post'

问题描述 投票:0回答:1

存在完整错误:“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
django django-models django-views django-templates recipe
1个回答
0
投票

根据错误,模板中很可能没有名为

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
类似的项目。如果没有记录被删除,我们将继续创建一条记录。


注意:您可以使用以下命令将视图限制为经过身份验证的用户

@login_required
装饰器[Django-doc].


注意:函数通常用 snake_case 编写,而不是 PascalCase,因此它是 建议将函数重命名为

like
,而不是
LikeView


注意:您可以使用

redirect(…)
 [Django-doc] 代替 第一次调用
reverse(…)
 [Django]
和 然后将其包装在
HttpResponseRedirect
对象[Django-doc]
中。
redirect(…)
函数不仅提供了更方便的签名来执行此操作,它还例如将使用
.get_absolute_url()
方法[Django-doc]
如果你传递给它一个模型对象。

© www.soinside.com 2019 - 2024. All rights reserved.