我的数据格式如下:
collection_name | type | manufacturer | description | image_url
---------------------------------------------------------------------------
beach | bed | company a | nice bed | 1.jpg
beach | king bed | company a | nice bed | 1.jpg
beach | nightstand | company a | nice ns | 1.jpg
grass | chest | company a | nice chest | 2.jpg
apple | chest | company a | nice chest | 3.jpg
fiver | chest | company b | good chest | 4.jpg
和类似的模型:
class Product(models.Model):
collection_name = models.TextField(null='true',blank='true')
type = models.TextField(null='true',blank='true')
manufacturer = models.TextField(null='true',blank='true')
description = models.TextField(null='true',blank='true')
image_url = models.TextField(null='true',blank='true')
此刻我要在我的应用中做什么?
我要这样做的原因是,如您在上面的示例数据中所看到的,不同的产品有时会重用同一张图像(某些图像在一幅图像中显示多个产品)。我只希望显示一次每个图像,同时能够显示与给定图像相关联的所有产品(其中可能有多个)。
我一直在基于this答案考虑做类似以下的事情,我认为它遵循上面给出的逻辑,但是我不确定这是正确的方法。
collectionname = product.objects.filter(id=id).values('collection_name').distinct()
images = product.objects.filter(collection_name__in=collectionname).values("image_url").distinct()
results = []
for img in images:
pbis = product.objects.filter(collection_name__in=collectionname, image_url=img['image_url'])
obj = {"image": img['image_url'], "items":[{"attr":pbi.attr, ...} for pbi in pbis]}
results.append(obj)
在这里,我的方法有哪些明显的错误?有没有更好,更清洁的方法?如果相关,则后端为postgres。
我想要在模板中执行的操作如下:
{% for instance in image_url %}
{{ collection_name }} Collection:
<img src="{{ instance }}">
Product type: {{ instance.type }}
Product Description: {{ instance.description }}
{% endfor %}
应该输出以下内容:
对于1.jpg:
Beach Collection
<img src="1.jpg">
Product type: bed
Product Description: nice bed
Product type: king bed
Product Description: nice bed
Product type: nightstand
Product Description: nice ns
对于2.jpg:
Grass Collection
<img src="2.jpg">
Product type: chest
Product Description: nice chest
对于3.jpg:
Apple Collection
<img src="3.jpg">
Product type: chest
Product Description: nice chest
对于4.jpg:
Fiver Collection
<img src="4.jpg">
Product type: chest
Product Description: good chest
答案 0 :(得分:1)
听起来好像有几个额外的模型可以更轻松地处理您的内容:Collection
和Image
。对于您的图片模型,我建议您使用Django的ImageField
,它的功能比仅仅将URL保存为文本更全面。要使用ImageField,您需要安装Pillow
,它是Python图像库(PIL
)当前维护的分支。使用命令行上的pip install Pillow
执行此操作。 ImageField具有内置属性url
,因此您仍然可以轻松访问图像的URL(请参见下面的模板)。然后您的新models.py可以是:
# models.py
class Image(models.Model):
source = models.ImageField(upload_to='my_media_path')
class Collection(models.Model):
name = models.CharField(max_length=30)
products = models.ManyToManyField(Product, blank=True)
feature_image = models.ForeignKey(Image, related_name='collections', on_delete=models.SET_NULL)
class Product(models.Model):
...
image = models.ForeignKey(Image, related_name='products', on_delete=models.SET_NULL)
# or ManyToManyField if a product has several images
然后,您将获得与所选产品具有相同图像的其他产品:
bucket = Product.objects.get(pk=1)
bucket.image.products.all()
<Product: Bucket>
<Product: Spade>
对于您的模板-主要按集合组织内容:
# query
collections = Collection.objects.all()
# template.html
{% for collection in collections %}
<h1>{{ collection.name }}</h1>
<img src="{{ collection.feature_image.source.url }}">
{% for product in collection.products.all %}
<p>{{ product.name }}</p>
<p>{{ product.description }}</p>
{% endfor %}
{% endfor %}
编辑:
没有时间实施上述方法,那么您提到的方法将可以正常工作。您可以在视图代码中更改一行以使其更简单:
...
obj = {"image": img['image_url'], "items": pbis}
然后将results
字典传递给模板上下文时:
{% for collection in results %}
{{ collection.items.0.collection_name }} Collection:
<img src="{{ collection.image }}">
{% for item in collection.items %}
<p>Product type: {{ item.type }}</p>
<p>Product Description: {{ item.description }}</p>
{% endfor %}
{% endfor %}