Django 2.2 + DetailView具有过滤功能的多个模型

时间:2019-04-11 21:31:40

标签: django django-views django-class-based-views

我正在尝试使我的三个模型在一个DetailView上正常工作。我已经加载了所有图像,但是包含图像的模型始终显示第一个图像。我知道我需要以某种方式对其进行过滤,但是我真的不知道该怎么做。由于我需要产品信息来过滤图像。这是我的代码:

观看次数:

class VendorDetailView(DetailView):
    context_object_name = 'vendor_detail'
    model = Vendor
    queryset = Vendor.objects.all()
    template_name = 'vendor_details.html'

    def get_context_data(self, **kwargs):
        context = super(VendorDetailView, self).get_context_data(**kwargs)
        context['products'] = Product.objects.filter(vendor=self.get_object())
        context['image'] = ProductImage.objects.all()
        return context

型号:

class Product(models.Model):
    product_model = models.CharField(max_length=100)
    vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
    slug = models.SlugField(max_length=200, unique=True, null=True)
    length = models.CharField(max_length=50)
    length_range = models.ForeignKey(LengthRange, on_delete=models.SET_NULL, null=True, blank=True)
    hull_type = models.ForeignKey(Hull, on_delete=models.SET_NULL, null=True, blank=True)
    max_beam = models.CharField(max_length=50, blank=True, default='0')
    cockpit_length = models.CharField(max_length=50, blank=True, default='0')
    cockpit_beam = models.CharField(max_length=50, blank=True, default='0')
    price = models.DecimalField(decimal_places=2, max_digits=50)
    power = models.ForeignKey(PowerConfiguration, on_delete=models.SET_NULL, null=True, blank=True)
    average_bare_hull_weight = models.CharField(max_length=50, blank=True, default='0')
    fuel_capacity = models.CharField(max_length=50, blank=True, default='0')
    seating_capacity = models.ForeignKey(Seat, on_delete=models.SET_NULL, null=True, blank=True)
    speed = models.ForeignKey(SpeedRange, on_delete=models.SET_NULL, null=True, blank=True)
    warranty = models.CharField(max_length=256, default='None')
    hull_only_available = models.BooleanField(blank=False, default=False)
    description = models.TextField()
    featured = models.BooleanField(blank=False, default=False)

    class Meta:
        ordering = ['product_model']

    def __str__(self):
        return '{} {}'.format(self.vendor, self.product_model)

    def save(self, *args, **kwargs):
        # just check if product_model or vendor.name has changed
        self.slug = '-'.join((slugify(self.vendor.name), slugify(self.product_model)))
        super(Product, self).save(*args, **kwargs)

class ProductImage(models.Model):
    product = models.ForeignKey(Product, related_name='images', on_delete=models.CASCADE)
    image = models.ImageField(upload_to='product_images', blank='img/92-thumb.jpg')

class Vendor(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(max_length=200, unique=True, null=True)
    website = models.CharField(max_length=256)
    vendor_email = models.CharField(max_length=100)
    images = models.ImageField(upload_to='vendor_images', blank='img/92-thumb.jpg')
    description = models.TextField()

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        # just check if product_model or vendor.name has changed
        self.slug = slugify(self.name)
        super(Vendor, self).save(*args, **kwargs)

模板:

<div class="preview col-md-4">

                        <div class="vendor-pic">
                            {% if vendor_detail.images %}
                                <div class="tab-pane">
                                    <img class="vendor-preview" src="{{ vendor_detail.images.url }}"/></div>
                            {% endif %}
                        </div>
**[snipped for brevity]**
                    </div>
                    <div class="details col-md-6">
                        <h3 class="vendor-title">{{ vendor_detail.name }} Boats</h3>
                        <p class="vendor-description">{{ vendor_detail.description | linebreaksbr }}</p>
                        <h5 class="website">website: <span>{{ vendor_detail.website }}</span></h5>
                    </div>
                </div>

{% for product in products %}

            <div class="product-card">
                <div class="product">
                    <div class="top">{% for product_image in image.all %}
                        {% if product_image.image %}
                            <img class="product-img" src="{{ product_image.image.url }}">
                        {% endif %}
                    {% endfor %}
                    </div>
                    <div class="bottom">
                        <div class="left">
                            <div class="details">
                                <h3>{{ product.vendor }} {{ product.product_model }}</h3>
                                <p>Starting at ${{ product.price|intcomma }}</p>
                            </div>
                            <div class="buy"><a
                                    href="{% url 'boatsales:product_detail' product.slug %}"><i
                                    class="material-icons">pageview</i></a></div>
                        </div>
                    </div>
                </div>
                <div class="inside">
                    <div class="icon"><i class="material-icons">info_outline</i></div>
                    <div class="contents">
                        <p style="text-align: justify">{{ product.description|linebreaksbr }}</p>
                    </div>
                </div>
            </div>
        {% endfor %}

我尝试了多种方法来过滤产品图像,但是我唯一能使用的是ProductImages.objects.all()这当然是不正确的。您能提供的任何帮助将不胜感激。预先感谢。

1 个答案:

答案 0 :(得分:0)

您不需要图像的查询集,可以使用Product通过related_name实例访问它们,如下所示:

{% for product in products %}
  <div class="product-card">
    <div class="product">
      <div class="top">
        {% for product_image in product.images.all %}
          <img class="product-img" src="{{ product_image.image.url }}">
        {% endfor %}
      </div>
      ...
  </div>
{% endfor %}