I Have a table Product
and a table Variation
, Variation
has ManyToOne
relation i.e. ForeignKey
with the table.
I want only first object
of Variation
, so that I can render it fields, which I want.
The way I am currently implementing to call the first object in html page:
{{item.variation.price_set.first}}
Note:
{{item}} is my product object or instance.
Html file:
<div >
{% for item in TopItems %}
{% if item.image %}
<div >
<img 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 >
{{item.variation.promotion_price}}
</h2>
<h2 >
{{item.variation.price}}
</h2>
{% else %}
<h2 >
{{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, the below method is passing all records to the template.
def get_context_data(self, **kwargs):
context["TopItems"]= Product.objects.filter(top_item=True)
So, How can I get only first record of variaton
, so that I can show respective prices?
CodePudding user response:
You can use nested
loops, for accessing only first promotion price as well as price
in the following way:
This is a minimal reproducible example, as not able to understand your design.
{% 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 betweentemplate
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 insnake_case
rather thanPascalCase
, so it can be passed astop_items
rather thanTopItems
.