2009-08-15 92 views
4

所以问题就出在这里。想象两种模式:摄影师和照片。严格的规则是,图片只能有1位摄影师,所以在Photo中有摄影师的ForeignKey链接。现在ForeignKey和Django Template


class Photographer(models.Model): 
    name = models.CharField(max_length = 40) 

class Photo(models.Model): 
    name = models.CharField(max_length = 40) 
    photographer = models.ForeignKey(Photographer) 

我想显示在主页上最有名的摄影师用3张最流行的他的照片。所以它应该是这样的:


# views.py 
def main(request): 
    photographers = ... 
    return render_to_response("main_page.html", { 
       "photographers": photographers 
      }) 

#main_page.html 
{% for photo in photographers.photo_set.all()[:3] %} 
{{ photo.name }} 
{% endfor %} 

但Django模板系统不允许all()和[:3]。那么最好的办法是什么?最明显的解决方案是动态创建对象(从摄影师和照片创建数组并将其传递给模板),但我不认为这是一个好方法。

请不要只是参考我Django的手册,我仔细阅读,但无法找到答案...

+0

我刚刚添加了一个答案,其实或多或少是你在评论中所说的:-) – 2009-08-15 18:08:02

回答

6

尝试使用slice filter

{% for photo in photographers.photo_set.all|slice:":3" %} 

注意,.all并不需要显式调用。

+0

这很好用!实际上,我自己发现了一种更通用的方法:向摄影师get_top3photos(self)添加一个方法,它只返回自我。所以在模板中,我可以参考这个新的属性{%for photographer.top_3_photos%} photo – Vitaly 2009-08-15 17:54:50

+0

是的,将选择移出模板是你最好的选择。将其放入视图或模板标签中。 – hughdbrown 2009-08-16 19:30:10

1

你猜对了,你只需要逻辑移动到视图,只要将模板传递给对象就可以了。

# views.py 
def main(request): 
    photographers = photographers.photo_set.all()[:3] 
    return render_to_response("main_page.html", { 
       "photographers": photographers 
      }) 

#main_page.html 
{% for photo in photographers %} 
{{ photo.name }} 
{% endfor %} 

确保您的视图包含逻辑,模板只显示数据。

+0

是的,但我也需要在一个页面上显示摄影师的名字......所以它会像“摄影师约翰雨,照片:photo1,photo2,photo3“。 – Vitaly 2009-08-15 17:51:06

2

我觉得尤瓦尔A几乎有它,但不完全 - 照片和摄影师似乎混在一起。我认为最好的方法是在Photographer模型上提供top_photos属性,该属性返回前3名(或多个)照片。然后:

 
{% for photographer in photographers %} 
Photographer: {% photographer.name %} 
Top Photos: 
{% for photo in photographer.top_photos %} 
{% photo.name} 
{% endfor %} 
{% endfor %} 

我漏掉了任何HTML在上面的格式,但希望的意图十分明显。