问题
I want to display products in a Campaign DetailView template.
In my project each campaign has a shop which contains products, so the flow is like,
Campaign --> Shop --> Products
Campaign models.py
class Campaign(models.Model):
team = models.OneToOneField(Team, related_name='campaigns', on_delete=models.CASCADE, null=True, blank=True)
shop = models.OneToOneField(shop_models.Shop, on_delete=models.CASCADE, null=True, blank=True)
Shop models.py
class Product(models.Model):
title = models.CharField(max_length=100)
description = models.CharField(max_length=700, null=True, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=0)
class Shop(models.Model):
product = models.OneToOneField(Product, related_name='shop_product', on_delete=models.CASCADE, null=True, blank=True)
product2 = models.OneToOneField(Product, related_name='shop_product2', on_delete=models.CASCADE, null=True, blank=True)
product3 = models.OneToOneField(Product, related_name='shop_product3', on_delete=models.CASCADE, null=True, blank=True)
DetailView
class CampaignDetail(DetailView):
model = Campaign
form_class = CampaignForm
pk_url_kwarg = 'pk'
context_object_name = 'object'
template_name = 'campaign_detail.html'
Template
{% for item in obj.shop_set.all %}
<div class="plan">
<a href="">
<h4>{{ item.title }}</h4>
<h5>{{ item.price }}</h5>
<img src="{{ item.image.url }}" alt="">
</a>
</div>
Fields turned out to be empty in the template. Any help would be appreciated.
回答1:
As they are related by OneToOneField, then you can access the values of shop from campaign details view like this:
{{ obj.shop }}
And if you want to access the products, then do it like this:
{{ obj.shop.product.title }}
{{ obj.shop.product.price }}
{{ obj.shop.product2.title }}
{{ obj.shop.product2.price }}
{{ obj.shop.product3.title }}
{{ obj.shop.product3.price }}
Update
Well, in that case I would recommend using ManyToMany relation between Product and Shop. So that, a product can be assigned to multiple shops, or a shop can be assigned to multiple product. Then you can define the relation like this:
class Shop(models.Model):
products = models.ManyToManyField(Product)
and if you want iterate through products for a shop, you can do it like this:
{% for product in obj.shop.products.all %}
{{ product.title }}
{{ product.name }}
{% endfor %}
回答2:
Your models are wrong anyway, but especially if you want to use a for loop. You don't need the OneToOneFields from Shop to Product, you just want one ForeignKey from Product to Shop.
class Product(models.Model):
shop = models.ForeignKey('Shop')
Now you can do:
{% for product in obj.shop.product_set.all %}
{{ product.title }}
{{ product.price }}
{% endfor %}
If you don't have any other fields on Shop at all, then you can delete that whole model and have the ForeignKey point directly at Campaign, then iterate over obj.product_set.all
.
来源:https://stackoverflow.com/questions/54069689/how-to-access-foreign-key-in-a-django-template-detailview