2011-06-02 14 views
23

tengo este modelo simplificado:acceso ForeignKey situado directamente en la plantilla de 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) 

Un Item puede tener muchas ItemImages. También tengo una plantilla de la prestación de los siguientes conjunto de datos desde el punto de vista:

items = Item.objects.all() 

Así que ahora me gustaría hacer algo como esto en la plantilla:

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

Pero obviamente eso no es posible. No de la plantilla directamente, al menos.

¿Cuál es la forma correcta de obtener el equivalente de la primera imagen dentro de la plantilla?

Respuesta

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

hermoso, esto es lo que estaba buscando, gracias! –

+1

esta es realmente una buena solución. siempre me olvido de la etiqueta con. – arie

+0

+1 Muy agradable. Siempre me olvido de 'con' también. – tatlar

7

Una forma posible sería iterar sobre todos los ItemImage s de este modo:

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

O usted podría añadir un método para su modelo Item:

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

y luego llamar a este método en su plantilla:

{{ item.get_first_image }} 

O podría usar:

{{ item.itemimage_set.all.0 }} 

y para obtener la URL de la primera imagen:

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

Aunque si necesita más flexibilidad (más de una imagen en ciertos casos, etc.) que es probablemente el mejor para escribir un poco templatetag.

3

Si desea que la primera imagen de conjunto que puede hacer:

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

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

{% endfor %} 

Pero también amo solución Andray con 'con'

+0

Esta no es una solución muy elegante. '{% with%}' lo resuelve completamente. –

2

esto funcionó para mí, utilice el related_name en su modelos.

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 %} 
Cuestiones relacionadas