【问题标题】:Django Simple Template Tag QuestionsDjango 简单模板标签问题
【发布时间】:2021-10-09 22:05:48
【问题描述】:

我是一名正在学习如何玩 Django 的学生。您将使用 Vault 中的模板标签输出 p-tag。我要使用的模板标签是“option.product_code和product.product_code在选项表中相同,如果有两个选项.option_code”。 if语句应该如何填写?

我想补充

你好

参考以上。请给我一些建议。

Models.py

class Product(models.Model):
    product_code = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200, db_index=True)
    image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)

    class Meta:
        ordering = ['product_code']

    def __str__(self):
        return self.name


class Option(models.Model):
    option_code = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['option_code']

views.py

def index(request):
        products = Product.objects.prefetch_related('option_set').annotate(noption=Count('option_set'))


    return render(request, 'option/option_list.html', {'products':products})

模板

{% for product in products %}
    {% for option in product.option_set.all %}
            {% if product.noption >= 2 %}

<p> hello! </p>

{% endif %}
{% endfor %}{% endfor %}

错误:

Cannot resolve keyword 'option_set' into field. Choices are: product_code, name, option

【问题讨论】:

  • 这确实属于模板,而是属于view。请分享相关模型和视图。
  • @WillemVanOnsem 选项表包括 option_code、optionn_name、product_code。产品表包含 product_code product_name, image。 Option的product_code注册了一个叫‘hat’的商品,option_name注册了size和color两个商品。查看에서는 product = Product.objects.all() Option.objects.all() 这就是全部。我只是想把 p-tag 放在那个条件下。
  • edit提问。
  • @WillemVanOnsem 我已经编辑了内容。感谢您的收看。
  • 这是一个 Django 被“固执己见”的例子。如果你想把复杂的逻辑放在模板中(不同的意见)你仍然可以使用 Django,但是你会想用 Jinja 模板引擎来使用它。 (我个人认为 Django 开发人员的意见往往是正确的)。

标签: django django-models django-rest-framework django-views django-templates


【解决方案1】:

你不应该在模板中加入。模板实现渲染逻辑,而不是业务逻辑。您可以通过以下方式枚举产品的相关Options:

{% for product in products %}
    <p>{{ product.name }}</p>
    {% for option in product.option_set.all %}
        option: {{ option.name }}
    {% endfor %}
{% endfor %}

因此,在视图中,您应该只传递products(而不是product,因为它是Products 的集合),并使用.prefetch_related(…) [Django-doc] 你可以防止进行 N+1 个查询:

def index(request):
    products = Product.objects.prefetch_related('option_set')
    return render(
        request,
        'option/option_list.html',
        {'products': products)
    )

【讨论】:

  • 你是一个很酷的开发者。谢谢。我会尝试按照你告诉我的方式运行它。谢谢。还有一件事想问你,stackoverflow.com/questions/68652095/…我很想知道我在这个链接中问的答案是否可行。
  • 我尝试了您建议的方法,但正如您所说,枚举产品相关选项没有问题。但是我要实现的是,只有在一个product_code中有两个或多个选项时才显示

    标签。我该怎么办?

  • @roboca:您可以使用条件注释Products,因此Product.objects.annotate(noption=Count('option_set')).prefetch_related('option_set'),然后您可以在模板(在{% for ... %})循环中使用{% if product.noption &gt;= 2 %}。跨度>
  • .annotate(noption=Count('option_set') 表示未找到 option_set。product.objects 说未找到 option_set。我很难过。如果可以的话,我将不胜感激看看我修改的历史有没有问题,我加到body里了。
  • @roboca: 那你需要Count('option')
猜你喜欢
  • 1970-01-01
  • 2011-07-22
  • 2011-08-24
  • 1970-01-01
  • 2016-02-28
  • 1970-01-01
  • 2011-10-22
  • 1970-01-01
  • 2011-02-26
相关资源
最近更新 更多