Django -使用外键显示产品列表

zzwlnbp8  于 2023-05-19  发布在  Go
关注(0)|答案(2)|浏览(170)

我有一个Product模型和一个ProductCustomField模型,其中包含每个产品的所有规范。它有一个返回Product的外键。
我只是希望能够列出每个产品沿着该产品的规格。正如代码现在所示,对于每个产品,它显示了所有产品的规格。
模型化

class Product(models.Model):
    name = models.CharField(max_length=255, unique=True)

    def __str__(self):
        return self.name[:50]

class ProductCustomField(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    key = models.CharField(max_length=255)
    value = models.CharField(max_length=255)

    def __str__(self):
        return self.key[:50]

观点

def product_lines_view(request):
    context = {
        'product_list': Product.objects.all(),
        'spec_list': ProductCustomField.objects.all(),
    }
    return render(request, 'product_lines/product_list.html', context)

模板

{% for product in product_list %}
    <h2>{{ product.name }}</h2>
    <ul>
        {% for spec in spec_list %}
            <li>{{ spec.key }}</li>
            <li>{{ spec.value }}</li>
    </ul>
        {% endfor %}
{% endfor %}
ngynwnxp

ngynwnxp1#

您不需要加载每个规范并将其传递给spec_list,这就是您多次查看所有规范的原因。
您的视图可能如下所示:

def product_lines_view(request):
    context = {
        'product_list': Product.objects.all(),
    }
    return render(request, 'product_lines/product_list.html', context)

您的模板可能看起来像这样:

{% for product in product_list %}
    <h2>{{ product.name }}</h2>
    <ul>
        {% for spec in product.productcustomfield_set.all %}
            <li>{{ spec.key }}</li>
            <li>{{ spec.value }}</li>
        {% endfor %}
    </ul> 
{% endfor %}

解释是,Django自动设置了一个反向关系属性,该属性由它具有关系的模型的名称和后缀_set组成。因此,通过这样做,您将获得与每个特定产品有关系的每个ProductCustomField
您可以使用关键字related_name更改此行为,方法是在www.example.com上执行models.py:

class ProductCustomField(models.Model):
    product = models.ForeignKey(
        Product, 
        on_delete=models.CASCADE, 
        related_name="specs"
    )
    key = models.CharField(max_length=255)
    value = models.CharField(max_length=255)

    def __str__(self):
        return self.key[:50]

你可以这样调用模板:

{% for product in product_list %}
    <h2>{{ product.name }}</h2>
    <ul>
        {% for spec in product.specs.all %}
            <li>{{ spec.key }}</li>
            <li>{{ spec.value }}</li>
        {% endfor %}
    </ul> 
{% endfor %}

你应该知道这是一个突破性的变化,所有目前使用productcustomfield_set的地方将不再工作,应该改为specs
以下是django related_name关键字的文档:https://docs.djangoproject.com/en/4.0/ref/models/fields/#django.db.models.ForeignKey.related_name

6yjfywim

6yjfywim2#

首先,在你的上下文中不需要“spec_list”:

context = {
    'product_list': Product.objects.all(),
}

只需更改模板:

{% for product in product_list %}
    <h2>{{ product.name }}</h2>
    <ul>
    {% for spec in product.productcustomfield_set.all %}
        <li>{{ spec.key }}</li>
        <li>{{ spec.value }}</li>
</ul>
    {% endfor %}
{% endfor %}

相关问题