我想创建一个页面,我可以在网页上按照图片显示属性。
目前,My Property模型看起来像这样(一些代码被取出):
class Property(models.Model):
PROPERTY_TYPE = (('Room', 'Room'), ('House', 'House'))
type = models.CharField(max_length=100, choices=PROPERTY_TYPE)
title = models.CharField(max_length=100, db_index=True)
beds = models.IntegerField(null=True, blank=True)
price = models.IntegerField()
payment_term = models.CharField(choices=PAYMENT_TERM_CHOICES, max_length=50)
和图片模型
class Picture(models.Model):
location = models.CharField(max_length=255)
owner = models.ForeignKey(User)
active = models.BooleanField(default=True)
alt = models.CharField(max_length=100)
parent_property = models.ForeignKey(Property, null=True)
timestamp = models.DateTimeField(default=timezone.now)
在我看来,我得到像这样的对象列表:
room_list = Property.objects.all().filter(type='Room').order_by('timestamp')[6]
当通过传递的room_list列表运行for循环时,我想像
一样引用它会议室的第一张图片列表
我尝试过关于一对多关系的Django官方文档,但我似乎无法遵循它。
我将如何实现这一目标?
答案 0 :(得分:1)
虽然你可以使用这样的东西:
{% for room in room_list %}
<img src="{{ room.picture_set.first }}"/>
{% endfor %}
我不推荐它。原因是,对于每个room_list项,您将转到图片项的数据库。因此,当您有30个项目时,您将使用31个查询轰炸数据库。
你可以做的最简单的事情就是为你添加另一个字段属性模型,比如default_picture,默认情况下将FK添加到Picture with None。保存图片后,您将填写该图片的ID(您使用的图片以及如何处理没有图片的记录在您的业务逻辑上)。然后你就这样得到记录:
room_list = Property.objects.filter(
type='Room'
).select_related(
'default_picture'
).order_by('timestamp')[6]
这将导致单个查询。当然还有另一种方法可以达到同样的效果,但这些方法更复杂。
提示:您不需要按时间戳字段排序(除非您修改其值),但您可以使用ID,因为它是按顺序创建的。这是更便宜的操作(至少在Postgres中)。
更新: 正如@JamesLin建议的那样,你可以使用这样的东西:
room_list = Property.objects.filter(
type='Room'
).prefetch_related(
'picture_set'
)
这将被翻译成两个查询,一个用于Property列表,第二个用于与pull属性项相关的所有Picture记录(Django将以编程方式连接它们)。这对于程序员来说是相当懒惰的,但考虑到你正在为每个属性加载所有图片记录。但这肯定是比picture_set更好的解决方案,比我的第一个建议更容易实现(它不会自动意味着更好的解决方案)。
答案 1 :(得分:0)
room_list.picture_set.all()
是您访问图片集的方式。要获得第一个,您只需访问room_list.picture_set.first()
即可。模板版本:{{ room_list.picture_set.first }}
。
答案 2 :(得分:0)
在此处简单回答您的问题:
{% for room in room_list %}
<img src="{{ room.picture_set.first }}"/>
{% endfor %}
然后有一整个chapter来优化它。
BTW:
此查询只会为您提供第7宫
room_list = Property.objects.all().filter(type='Room').order_by('timestamp')[6]
你可能想要[:6]
此外,您无需在.all()
.filter()
room_list = Property.objects.filter(type='Room').order_by('timestamp')[:6]