【问题标题】:how to use a forloop such that the if the "IF" statement in the loop is satisfied the loop ends in Django Templates如何使用 for 循环,使得如果满足循环中的“IF”语句,则循环在 Django 模板中结束
【发布时间】:2019-04-27 14:07:15
【问题描述】:

我正在使用 2 个 Django 模型 ReviewItem。我想看看用户是否已经审查了该项目。如果是,他会看到评论分数。如果没有,他会看到查看项目的按钮

我有以下评论模型

class Review (models.Model):
    review_from = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='review_from')
    review_for = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='review_for')
    item = models.ForeignKey(OrderItem, related_name='items') 

在视图上下文中定义变量(伪代码)

admin = User.objects.get(username="admin")
admins_reviews = Review.objects.filter(review_from__username = "admin")

下面是我的模板

 {% for item in buyers_items %}
    {% for review in buyers_review%}
         {% if review.item.id == item.id %}
              <button class="text-success">Your rating<br/><b>{{review.ratings}}/10</b></button>
         {% else %}
              <a href="{% url ... %}">
                <button>Leave Review</button>
              </a>
          {% endif %}
    {% endfor %}
{% endfor %}

如果我这样做,我会收到以下错误

我该如何克服这个问题。

查看

from django import template
register = template.Library()

class OrderHistory(LoginRequiredMixin, ListView):
    model = Order
    template_name = 'order/order_list.html'

    def get_context_data(self, **kwargs):
        context = super(OrderHistory, self).get_context_data()
        context['order_details'] = Order.objects.filter(emailAddress=self.request.user.email)
        context['order_items'] = OrderItem.objects.filter(order__emailAddress=self.request.user.email)
        context['buyers_review'] = Review.objects.filter(review_from=self.request.user)
        print(context['buyers_review'])
        return context

自定义标签

    @register.filter()
    def review_bought_items(order_items, buyers_review):
        return buyers_review.filter(item__in=order_items).exists()

【问题讨论】:

  • 不清楚您遇到了什么错误?
  • @JonClements 我已经编辑了图像。我得到 2 个按钮,一个带有评论,一个显示离开评论。见上图。因为他们都有评论。
  • 所有这些逻辑都必须在你的后端完成,而不是在模板端。展示您的观点,以便我提供帮助
  • 如果您 c/p html 模板,则 {% endif %} 标记处有错字。
  • @Alex 我修复了它在实际代码中是正确的

标签: django python-3.x django-templates django-views


【解决方案1】:

根据我在您的模板中看到的内容,您可以使用标签过滤器或在您的视图中更简单地进行操作。让我们使用自定义标签:

@register.filter
def review_bought_items(buyers_items,buyers_review):
     return buyers_review.filter(item__in=buyers_items).exists()

现在在模板中你可以做

<!-- load the tag -->
{% load file %}

{% if buyers_items|review_bought_items:buyers_review %}
     <button class="text-success">Your rating<br/><b>{{review.ratings}}/10</b></button>
{% else %}
     <a href="{% url ... %}">Leave Review</a>
{% endif %}

【讨论】:

  • 我已经根据您的代码编辑了我的观点(请参阅上面的问题),这对您来说是否正确。
  • No @SamirTendulkar 不正确,自定义标签应该是一个单独的文件,看看here 看看如何编写自定义标签
  • 我相信它会起作用的,只是休息了一下。将在自定义标签上观看视频并在明天实施我非常感谢您回答这个问题
  • 好的,很高兴为您提供帮助!
  • 仍在努力。 {{review.ratings}} 仅适用于 forloop {% for review in buyers_review%} 如果我在您的代码中添加一个 forloop。就像我回到了第一方。我确定我做错了什么。这是我的个人项目,所以必须在我的日常工作之间进行这项工作。希望能通宵工作
【解决方案2】:

问题是您正在遍历所有buyers_reviews。在这种特殊情况下,您有 2 条买家评论,一条针对当前商品,一条针对不同商品。

第一个迭代将评估为False 第一个条件,它将显示所有Leave Review 按钮,第二次迭代将评估它为True 并显示“您的评分”块。

如果您不想移动后端的所有逻辑,可以使用模板标签来过滤基于item.id 的评论

【讨论】:

  • 我试图在视图中过滤它目前我的视图是context['buyers_review'] = Review.objects.filter(review_from=self.request.user) 我不确定如何过滤项目context['buyers_review'] = Review.objects.filter(review_from=self.request.user, item=self.kwargs.get("item")) 不起作用
  • 我不知道您的完整视图如何,但是您可以使用 cmets 部分中推荐的解决方案并创建自定义过滤器 (docs.djangoproject.com/en/2.1/howto/custom-template-tags) 并将其应用于模板而不是比较项目ID。
猜你喜欢
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
相关资源
最近更新 更多