【问题标题】:How To: For...Else in a Django template (if/else inside a for loop)如何:在 Django 模板中使用 For...Else(在 for 循环中使用 if/else)
【发布时间】:2022-01-25 15:48:49
【问题描述】:

如果已经有人问过这个问题,我提前道歉,但我找不到任何答案来回答我遇到的问题:

我需要在 Django 模板中执行类似于 For...Else 循环的操作。

我需要根据 if 条件在模板上显示一个按钮:

  • 如果用户已经购买了该产品,则显示按钮 1
  • 如果用户还没有购买过该产品,则显示按钮 2

对于每一个产品,我都要浏览用户的购买情况,然后根据他们是否已经购买了该产品,显示一个或另一个按钮。

代码的简化(和错误)版本如下:

{% for product in products %}
  //other code here

  {% for purchase in purchases %}
     {% if purchase.service_id.id == product.id %}
       // show button 1
     {% else %}
       // show button 2
     {% endif %}
  {% endfor %}

{% endfor %}

但是,此代码不起作用,因为它在通过 for 循环时显示了两个按钮。

我不能执行 For...Empty,因为用户可能有其他购买(因此 for 循环不会为空),但它们都与该产品不相符。

提前致谢。

编辑:

感谢@JashOFHop 的回复!最后,我找到了解决办法。我会分享它以防其他人发现自己处于这种情况:

为清楚起见,本案例涉及的模型为:

class User(AbstractUser):
    pass

class Service(models.Model):
    user_id = models.ForeignKey("User", on_delete=models.CASCADE, related_name="user_id_services")
    name = models.CharField(max_length=64)
    status = models.BooleanField(default=True)
    description = models.TextField(max_length=300)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="category_name")
    price = models.IntegerField()
    slots = models.IntegerField(default=1)
    amount = models.IntegerField(default=1)
    watchedby = models.ManyToManyField(User, blank=True, related_name="watchedby")

class Purchase(models.Model):
    user_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_id_purchases")
    service_id = models.ForeignKey(Service, on_delete=models.CASCADE, related_name="service_id_purchases")
    amountpaid = models.IntegerField()

此模板的视图

def explore(request):

    # get all the active services from the db
    services = Service.objects.filter(status=True).order_by('name')

    # get the catogories for the filter option
    categories = Category.objects.all().order_by('category')

    # get the info of the user
    userinfo = User.objects.get(username=request.user)

    # get the info of the user's purchases
    purchases = Purchase.objects.filter(user_id=userinfo)

    # render the template
    return render(request, "barter/explore.html", {
        "services": services,
        "categories": categories,
        "userinfo": userinfo,
        "purchases": purchases
    })

如上所述,模板呈现了所有服务,并且每个服务都应该检查该用户是否已经购买了所述服务。

解决方案:

在视图中我添加了这个并将它也传递给了模板:

# create a list of the IDs of the services purchased by the user to be able to render the buy/bought button correctly
    purchases_list = []
    for purchase in purchases:
        purchases_list.append(purchase.service_id.id)

那么,模板是:

{% for service in services %}
   // other code with infomation of the service here

   // Important part:
   {% if service.id in purchases_list %}
     <button>You already bought this service</button>
   {% else %}
     <button>Buy now</button>
   {% endif %}

{% endfor %}

【问题讨论】:

  • 如果没有看到您的 models.py、views.py 和更多模板,则无法解决此问题。

标签: django for-loop if-statement django-templates


【解决方案1】:

您可以创建其他模型,例如 Profile

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    cart = models.MenyToManyField(Product, null=True)

所以在 byu 按钮的视图中你可以这样写

def buy(request, pk): #byu button
    product = Product.objects.get(id=pk)
    profile = Profile.objects.filter(user.username=request.user)
    profile.cart.add(product.id)
    return redirect('some html')

另一个按钮也一样

def index(request, pk): # for template
    product = Product.objects.get(id=pk)
    profile = Profile.objects.filter(user.username=request.user)
    return response(request, 'some html', context)

模板

{% for i in product%}
 {% for products in profile%}
     {% for p in products.cart.all %}
       {% if i.id in p.id%}
       <p>you bought</p>
       {% else %}
        <a href='byu'>Buy</a>
       {% endif %}
      {% endfor%}
    {% endfor%}
 {% endfor%}

但我认为还有另一种最简单的方法可以解决您的问题

【讨论】:

    猜你喜欢
    • 2017-08-02
    • 2019-12-04
    • 2016-01-29
    • 2012-11-13
    • 1970-01-01
    • 2021-12-21
    • 2016-09-21
    • 2013-04-23
    • 2019-11-03
    相关资源
    最近更新 更多