2013-01-13 7 views
5

Si consideri il seguente modello Amicizia, dove per ogni amicizia fatta, c'è un utente che ha inviato la richiesta di amicizia, e un utente che ha ricevuto la richiesta di amicizia:Django: query per ottenere User.usernames tramite chiave esterna

from django.contrib.auth.models import User 

class Friendship(models.Model): 
    sender = models.ForeignKey(User) 
    receiver = models.ForeignKey(User) 

Come potrei costruire una query che mi avrebbe dato tutti i nomi utente degli utenti che si trovano in un'amicizia con, diciamo, user123?

Tenete a mente, user123 potrebbe essere il mittente o il destinatario di qualsiasi amicizia cui si trova.

Inoltre, voglio solo i valori user.username da restituire, non un intero oggetto utente.


Finora, ho questo mezzo/soluzione goffo (sto usando list() modo che io possa aggiungere che ricevono gli amici, sia di user123 e invio amici di user123, al fine di produrre un elenco di tutti gli amici) . Il problema è che sto ricevendo tutti gli oggetti User e desidero solo i nomi utente ... e deve esserci un modo migliore per farlo.

friends_a = list(Friendship.objects.filter(sender=user123).values('receiver')) 
friends_b = list(Friendship.objects.filter(receiver=user123).values('sender')) 
friends_a = [] if not friends_a else friends_a[0].values() 
friends_b = [] if not friends_b else friends_b[0].values() 
all_friends = friends_a + friends_b 

risposta

4

Q Objects for complex lookups.

Wow, questo è sorprendentemente una piegatrice mente per ottenere il risultato che si desidera impostare in quanto c'è in realtà 2 diverse query logici. Il modo più semplice è ... di spiegarlo con Python.

user = User.objects.get(username='user123') 
friendships = Friendship.objects.filter(Q(receiver=user) | Q(sender=user)) 

usernames = [] 

for friendship in friendships: 
    if friendship.receiver == user: 
     usernames.append(friendship.receiver.username) 
    else: 
     usernames.append(friendship.sender.username) 
+0

Accidenti, ben fatto. Speravo di riuscire a ottenerlo con una singola query complessa, ma questo ha sicuramente portato a termine il lavoro. – sgarza62