Django 简单模板标签问题

Posted

技术标签:

【中文标题】Django 简单模板标签问题【英文标题】:Django Simple Template Tag Questions 【发布时间】: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 开发人员的意见往往是正确的)。 【参考方案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)
    )

【讨论】:

你是一个很酷的开发者。谢谢。我会尝试按照你告诉我的方式运行它。谢谢。还有一件事想问你,***.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')

以上是关于Django 简单模板标签问题的主要内容,如果未能解决你的问题,请参考以下文章

带有“带有模板标签”方法的 django 静态文件

Django模板如何对简单标签返回的结果应用过滤器

AngularJS 与 Django - 模板标签冲突

AngularJS 与 Django - 冲突的模板标签

AngularJS 与 Django - 冲突的模板标签

如何从 python 代码中调用 django 模板标签?