2010-09-20 13 views
5

Sono un novizio del django, quindi la domanda potrebbe essere stupida, ma per favore sentitevi liberi di insegnarmi la strada giusta se lo sapete. Ho provato a cercare su Google il problema, ma sono ancora in perdita. Ecco il mio problema:Due chiavi esterne e un valore nel modello django

Ho una classe nel mio modello che ha due chiavi esterne:

class X(models.Model): 
    name = models.CharField(max_length=30) 
    def __unicode__(self): 
     return name 

class Y(models.Model): 
    name = models.CharField(max_length=30) 
    def __unicode__(self): 
     return name 

class Z(models.Model): 
    name = models.CharField(max_length=30) 
    x = models.ForeignKey(X) 
    y = models.ForeignKey(Y) 
    def __unicode__(self): 
     return name 

A mio avviso ho un elenco parziale degli oggetti X e una lista parziale degli oggetti Y in questo modo:

def MyView(x_pattern, y_pattern): 
    x_list = X.objects.filter(name__contains=x_pattern) 
    y_list = Y.objects.filter(name__contains=y_pattern) 
    z_list = Z.objects.all() 
    return render_to_response({'x_list': x_list, 'y_list': y_list, 'z_list': z_list}) 

Nel mio modello mi piacerebbe essere in grado di visualizzare una tabella in questo modo:

<table> 
    <tr> 
    <td>Y</td> 
    {% for x in x_list %} 
    <td>{{ x }}</td> 
    {% endfor %} 
    </tr> 
    {% for y in y_list %} 
    <tr> 
    <td>{{ y }}</td> 
    {% for x in x_list %} 
    <td> 
     <!-- here I need help: 
      I need to display z[x, y] if it exists, or "N/A" otherwise. 
     --> 
    </td> 
    {% endfor %} 
    </tr> 
    {% endfor %} 

Come faccio a farlo correttamente in django?

La ringrazio molto,

risposta

0

Si dovrebbe tenere la logica nel vostro punto di vista. Perché non filtra semplicemente la lista z?

z_list = Z.objects.filter(x__name__contains=x_pattern, y__name__contains=y_pattern) 
+0

Posso filtrare l'elenco nella vista, ma ancora non mi aiuta a visualizzarlo correttamente (cioè devo mappare (x, y) la coppia di chiavi al valore z [x, y] nel modello per poter visualizzare in una cella di tabella corretta). Mi sto perdendo qualcosa qui? – mfynf

1

Come @DZPM suggested, si dovrebbe pensare di mantenere la logica nel vostro punto di vista. [imbarazzato] Una volta ho inventato la mia struttura dati "Table" per fare qualcosa di molto simile. La tabella ha avuto righe corrispondenti a X, colonne corrispondenti a Y e celle corrispondenti a Z[X, Y]. Ho quindi scritto i filtri get_row e get_cell per fare il trucco nel modello. [/ sheepish]

Detto questo, ciò che si desidera può essere ottenuto utilizzando una coppia di filtri personalizzati. Questa soluzione è piuttosto prolissa.

@register.filter 
def x_is(value, x): 
    return value.x == x 

@register.filter 
def y_is(value, y): 
    return value.y == y 

È possibile utilizzare questi filtri nel modello come illustrato di seguito:

{% if z|x_is:x and z|y_is:y %} 
    {{ z }} 
{% else %} 
    N/A 
{% endif %} 
+0

Bingo! Grazie mille - questo era il link mancante (filtri personalizzati). – mfynf

0

Un altro approccio sarebbe quello di creare un generatore nella vista, e poi inviarlo al tuo contesto modello:

# nested inside your view function 
def x_and_z_list(y): 
    for x in x_list: 
     z_obj = x.z_set.filter(y=y) 
     z_name = z_obj or 'N/A' 
     yield {'x': x, 'z': z_name} 
return render_to_response('mytemplate', {'list_generator': x_and_z_list} 

Poi il modello potrebbe essere la seguente:

{% for y in y_list %} 
    <tr> 
     <td>{{ y }}</td> 
     {% for pair in list_generator.y %} {# pair is the dict you yielded before #} 
      <td>{{ pair.x.name }}: {{ pair.z }}</td> 
     {% endfor %} 
    </tr> 
{% endfor %} 
0

Ho combinato i concetti di filtro personalizzato e funzioni come oggetti di prima classe creando un filtro modello in un functor (oggetto-funzione).

Ecco quello che ho finito per fare:

def z_filter(x, y): 
    z_list = list(Z.objects.filter(x, y)) 
    return z_list.pop().name or 'N/A' 
register.filter(z_filter) 

in Template:

{% load z_filter %} 
<table> 
<tr> 
    <td>Y</td> 
    {% for x in x_list %} 
    <td>{{ x }}</td> 
    {% endfor %} 
</tr> 
{% for y in y_list %} 
    <tr> 
    <td>{{ y }}</td> 
    {% for x in x_list %} 
    <td>{{ x|z_filter:y }}</td> 
    {% endfor %} 
    </tr> 
{% endfor %} 
</table> 

Grazie a tutti per il vostro aiuto!

Problemi correlati