I don't know how to describe this exactly in database jargon. I would like to output an object that is in a relationship with another like this. order__orderitem.product.title
models.py
class Order(models.Model):
status_types = [
("Ordered", "Ordered"),
("Sent", "Sent"),
("Delivered", "Delivered"),
("Extended", "Extended"),
("Returned", "Returned"),
]
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
order_date = models.DateTimeField()
return_date = models.DateTimeField(null=True)
status = models.CharField(choices=status_types, default="Ordered", max_length=100)
total = models.IntegerField(null=False)
payment = models.OneToOneField(Payment, on_delete=models.CASCADE, null=False, blank=False)
shipping = models.ForeignKey(Shipping, on_delete=models.CASCADE, null=False, blank=False)
first_name = models.CharField(max_length=255, null=False, blank=False)
last_name = models.CharField(max_length=255, null=False, blank=False)
phone = models.CharField(max_length=12, null=False, blank=False)
city = models.CharField(max_length=255, null=False, blank=False, default=None)
zip_code = models.CharField(max_length=10, null=False, blank=False, default=None)
street = models.CharField(max_length=255, null=False, blank=False, default=None)
building_number = models.CharField(max_length=10, null=False, blank=False, default=None)
apartment_number = models.CharField(max_length=10, null=True, blank=True, default=None)
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
order = models.ForeignKey(Order, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
price = models.IntegerField(null=False, blank=False, default=15)
debt = models.IntegerField(null=True, default=0)
orders.html
{% for item in object_list %}
{% for it in item__OrderItem %}
{{ it.product.title }}
{% endfor %}
{% endfor %}
Is it possible in such a way?
Yes, you work with:
{% for item in object_list %}
{% for it in item.orderitem_set.all %}
{{ it.product.title }}
{% endfor %}
{% endfor %}
In the view, it is better to prefetch the items already, to prevent an N+1 problem with:
from django.db.models import Prefetch
class MyListView(ListView):
model = Order
queryset = Order.objects.prefetch_related(
Prefetch('orderitem_set', OrderItem.objects.select_related('product'))
)
while not necessary, this will result in two queries, whereas without this, it will require m×n+n+1 queries with N the number of Orders
and m the number of OrderItem
s.