2011-06-02 43 views
23

我有這樣的簡化模型:訪問ForeignKey的直接設置在模板在Django

class Item(models.Model): 
    name = models.CharField(max_length=120) 

class ItemImage(models.Model): 
    image = models.ImageField(upload_to='upload_dir') 
    item = models.ForeignKey(Item) 

Item可以有很多ItemImages。我也有一個模板呈現以下數據來自視圖設置:

items = Item.objects.all() 

所以現在我會想這樣做的模板:

{% for item in items %} 
<div> 
    {{ item.name }}<br> 
    <img src="{{ item.itemimage_set.all()[0] }}"> 
</div> 
{% endfor %} 

但顯然這是不可能的。至少不是直接來自模板。

什麼是獲得模板內第一個圖像的等價物的正確方法?

回答

40
{% with item.itemimage_set.all|first as image %} 
    <img src="{{ image.url }}" /> 
{% endwith %} 
+0

美麗,這就是我一直在尋找,謝謝! – 2011-06-02 19:42:27

+1

這真是一個不錯的解決方案。我總是忘記帶標籤。 – arie 2011-06-02 20:35:43

+0

+1非常好。我也總是忘記'與'。 – tatlar 2013-05-31 22:58:11

7

一種可能的方式是遍歷所有的ItemImage就像這樣:

{% for item in items %} 
<div> 
    {{ item.name }}<br> 
    {% for image in item.itemimage_set.all %} 
    <img src="{{ image.image.url }}"> 
    {% endfor %} 
</div> 
{% endfor %} 
9

或者你可以添加一個方法到你Item型號:

def get_first_image(self): 
    return self.itemimage_set.all()[0] 

,然後調用此方法您的模板:

{{ item.get_first_image }} 

或者您可以使用:

{{ item.itemimage_set.all.0 }} 

,並獲得第一圖像的URL:

<img src="{{ item.itemimage_set.all.0.url }}"> 

但如果你需要更多的靈活性(在某些情況下多張圖片,等等),它可能是最好寫一個小templatetag。

3

如果你想從組的第一張圖片,你可以這樣做:

{% for item in item.image_set.all %} 

{{if forloop.first }} 
<img src="{{ item.url }}"> 
{% endif %} 

{% endfor %} 

,但我也愛安德魯解決方案與「與」

+0

這不是一個非常優雅的解決方案。 '{%with%}'絕對可以解決它。 – 2012-01-10 11:10:39

2

這個工作對我來說,使用related_name在楷模。

models.py

class Building(models.Model): 
    address = models.CharField(max_length=200, blank=True, null=True) 
    city  = models.CharField(max_length=200, blank=True, null=True) 

class Space(models.Model): 
    title  = models.CharField(max_length=200, blank=True, null=True) 
    building = models.ForeignKey(Building, related_name="spaces_of_this_building") 

buildings.html

{% for space in building.spaces_of_this_building.all %} 
    {{ space.size }} 
{% endfor %}