如何通过 sub table Django 访问字段

How to access a field through a sub table Django

我有一个 table Product 和一个 table VariationVariationManyToOne 关系,即 ForeignKey 与table.

我只想要 Variation 的第一个 object,这样我就可以呈现我想要的字段。

我目前在 html 页面中调用第一个对象的方式:

{{item.variation.price_set.first}}

Note: {{item}} is my product object or instance.

Html 文件:

<div class="carousel-inner">
    {% for item in TopItems %}
        {% if item.image %}
            <div class="carousel-item active">
                <img class="d-block img-fluid mx-auto m-auto" src="{{item.image.url}}" alt="{{item.name}}">
                <p>{{item.name}}</p>
                <p>{{item.variation.price_set.first}}</p>
                <p>{{item.variation_set.first}}</p>
                {% if item.variation.promotion_price_set.first%}
                <h2 class="text-primary">
                    {{item.variation.promotion_price}}
                </h2>
                <h2 class="text-primary">
                    {{item.variation.price}}
                </h2>
                {% else %}
                <h2 class="text-primary">
                    {{item.variation.price}}
                </h2>
                {% endif %}
            </div>
        {% endif %}
    {% endfor%}
</div>

Models.py

class Product(models.Model):
    name = models.CharField(max_length=255)
    short_description = models.TextField(max_length=255)
    long_description = models.TextField(max_length=255, blank=True)
    image = ResizedImageField(
        size=[550, 300], quality=70, upload_to='product_images/%Y/%m/%d')
    #image = models.ImageField(upload_to='product_images/%Y/%m/%d')
    slug = AutoSlugField(unique=True, always_update=False,
                         populate_from="name")
    top_item = models.BooleanField(default=False)
    is_available = models.BooleanField(default=True)
    category = models.ForeignKey(
        Category, related_name="product", on_delete=models.CASCADE)
    subcategory = models.ForeignKey(
        SubCategory, related_name="sub", on_delete=models.CASCADE, null=True, blank=True)
    objects = models.Manager()
    available = AvailableManager()

    class Meta:
        ordering = ("name",)  # vai ser ordenado pelo nome não o ID

    def get_absolute_url(self):
        return reverse("product:detail", kwargs={"slug": self.slug})



class Variation(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    name = models.CharField(
        max_length=80, blank=True, null=True)
    price = models.FloatField()
    promotion_price = models.FloatField(blank=True, null=True)
    stock = models.PositiveIntegerField(default=1)
    is_available = models.BooleanField(default=True)
    availableVariation = AvailableManagerVariation()
    objects = models.Manager()

    def __str__(self):
        return self.name or self.product.name

Views.py,下面的方法将所有记录传递给模板。

def get_context_data(self, **kwargs):
    context["TopItems"]= Product.objects.filter(top_item=True)

那么,我怎样才能只获取 variaton 的第一条记录,以便显示各自的价格?

您可以使用 nested 循环,通过以下方式只访问第一个 promotion price as well as price

这是一个最小的可重现示例,因为无法理解您的设计。

{% for item in TopItems %}

<div>
    <p> {{item.name}} </p>
    <p>{{forloop.counter}}st variation</p>

    {% for variation in item.variation_set.all  %}
    {% if forloop.counter0 < 1 %}
        <p>First variation price of  - {{variation.price}}</p> 
        {% comment  %}It will give only first price {% endcomment %}
        <p>First variation promotion price - {{variation.promotion_price}}</p>
        {% comment  %}It will give only first promotion price{% endcomment %}
    {% endif %}
    {% endfor %}
</div>
<br>
{%endfor%}

Note: There must be a space between template tags, as so write it as {% endif %} not {%endif%}, similarly for {% endfor %} not {%endfor%}.

Note: It will be better, if you pass your context keys in snake_case rather than PascalCase, so it can be passed as top_items rather than TopItems.