Reputation: 980
I have found the solution for this but only by checking in views so far. I need to check in templates.
My view:
brands = Brand.objects.all()
for brand in brands:
brand.products = Product.objects.filter(brand=brand.id)
And so in my template I want to show all my brands but not those which do not have any product.
{% for brand in brands %}
{% if brand.product is not None %}
<!-- Displays brand -->
{% endif %}
{% endfor %}
Something like that, but the code is not None
doesn't work for empty querysets and it is still displaying brands with no objects in them. What can I do?
EDIT: Sharing model as requested.
class Brand(models.Model):
name = models.CharField(max_length=100, null=False)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=100, null=False)
brand = models.IntegerField(null=True)
price = models.DecimalField(max_digits=12, decimal_places=2, null=False)
def __str__(self):
return self.name
Upvotes: 0
Views: 2898
Reputation: 292
This simple solution using {% empty %} inside my for worked for me.
{% for detallesblog in object_list %}
<label for="detalles" class="negritatxt">Detalles</label>
<p>
{{ detallesblog.detalles }}
</p>
<label for="logo" class="negritatxt">Logo</label>
<p>
<img src="{% static 'uploads/' %}{{ detallesblog.logo }} " class="img-fluid" alt="{{ detallesblog.logo }}">
</p>
<label for="updated_at" class="negritatxt">Fecha de Actualización</label>
<p>
{{ detallesblog.updated_at }}
</p>
<a href="detallesblog/editar/{{ detallesblog.id }}" title="Editar" type="button" class="btn btn-primary">Editar Datos</a>
{% empty %}
"You have not yet edited the details of your Blog", press the "Edit Data" button to do so.
<
<a href="detallesblog/editar/{{ detallesblog.id }}" title="Editar" type="button" class="btn btn-primary">Editar Datos</a>
{% endfor %}
You can adapt it to your needs
Upvotes: 0
Reputation: 876
If you want to display something different when a collection is empty, check this out:
{% for i in list %}
// Do this in non - empty condition
{% empty %}
// Do this in empty condition
{% endfor %}
credit: GeeksForGeeks
Upvotes: 0
Reputation: 144
Your template should be like:
{% for brand in brands %}
{% if brand.product %}
<!-- Displays brand -->
{% endif %}
{% endfor %}
Upvotes: 2
Reputation: 477769
It is usually not a good idea to use IntegerField
s, etc. to represent relations. Django uses ForeignKey
[Django-doc] to implement such relations. There are multiple advantages for this: (1) it will add extra constraints to the database, such that the key can only refer to a real Brand
; and (2) you will have extra ways to retrieve the related Product
s.
The Product
model thus should have a ForeignKey
to the Brand
model, like:
class Product(models.Model):
name = models.CharField(max_length=100, null=False)
brand = models.ForeignKey(Brand, null=True, db_column='brand')
price = models.DecimalField(max_digits=12, decimal_places=2, null=False)
Here we leave the database structure itself intact, but it will add a ForeignKey
on it, as well as an index, making retrieving all products for a given Brand
much faster.
It is usually a bad idea to write (business)logic in templates. In fact one of the reasons why the Django template language does not allow to make calls with parameters, etc. is to avoid that people write business logic in the template. So I strongly advice you to shift the logic to the view.
You can retrieve the Brand
s that at least have one related Product
in the view with a one-liner:
Brand.objects.filter(product__isnull=False).distinct()
So it is not necessary to check each brand individually. Here we also check the existance of a Product
in a single query for all Brand
s, not an extra query per Brand
to check if there are related Product
s.
This will result in a query that looks like:
SELECT DISTINCT brand.*
FROM brand
INNER JOIN product ON brand.id = product.brand_id
WHERE product.id IS NOT NULL
Upvotes: 2