2012-04-18 12 views
10

Uprościliśmy moje modele, aby było jaśniejsze, co próbuję zrobić.Django: Uzyskiwanie dostępu do wielu obiektów za pośrednictwem innej relacji Wiele do wielu

(models.py w APP Zespoły)

from django.db import models 
from django.contrib.auth.models import User 
import datetime 

class Team(models.Model): 
    users = models.ManyToManyField(User) 
    team_title = models.CharField(max_length=200) 
    team_description = models.CharField(max_length=200) 

    def __unicode__(self): 
     return self.team_title 

(models.py w aplikacji Dokumenty)

from django.db import models 
import datetime 

class Document(models.Model):  
    teams = models.ManyToManyField("Teams.Team", blank=True) 
    document_title = models.CharField(max_length=200) 
    document_description = models.TextField() 

def __unicode__(self): 
    return self.document_title 

Co chcę osiągnąć jest coraz listę użytkowników, którzy są związane z Dokument, najpierw zbierając wszystkie zespoły związane z dokumentem, a następnie zbierając wszystkich użytkowników powiązanych z tymi zespołami.

Moje próby poszły tak daleko jak to coś

(view.py w APP dokumenty)

from django.contrib.auth.models import User 
from Documents.models import * 
from Teams.models import * 

def docUsers(request, doc_id): 
    current_document = Documents.objects.get(pk = doc_id) 
    associated_users = current_document.teams.all().users 

    .... 

Błąd: obiekt 'queryset' nie ma atrybutu 'użytkownicy'

associated_users = current_document.items.all().users.all() 

Błąd: Obiekt "QuerySet" nie ma atrybutu "użytkownicy"

associated_users = current_document.items.users.all() 

Błąd: obiekt 'ManyRelatedManager' nie ma atrybut 'użytkownicy'

Czy będę o to w niewłaściwy sposób?

Odpowiedz

13

No tak. current_document.teams.all() to zestaw zapytań - mniej więcej lista - zespołów. Nie ma sensu pytać o numer current_document.teams.all().users, ponieważ zapytanie nie ma atrybutu "użytkownicy", stąd błąd. users to atrybut każdego elementu zespołu w tym zestawie zapytań w ciągu. Jednym ze sposobów na zrobienie tego byłoby powtórzenie zapytania i zapytanie o użytkowników powiązanych z każdym zespołem.

Jednak byłoby to beznadziejnie nieefektywne - jedno połączenie z bazą danych dla każdej drużyny. O wiele lepszym sposobem jest bezpośrednie zapytanie do bazy danych: daj mi wszystkich użytkowników, którzy są w zespołach powiązanych z bieżącym dokumentem. W ten sposób:

User.objects.filter(team__documents=current_document) 
+1

Wciąż jestem zdezorientowany. powiązanie modeli zespołu z modelem dokumentów odbywa się od dokumentów do zespołu, a nie odwrotnie (wiem, że to nie jest najbardziej logiczne podejście, ale nie wolno mi zmieniać struktury modelu), więc jak mogę filtrować dokumentację zespołu? – Finglish

+1

@agf 1. Nie, używaj rzeczywistych nazw modeli w wyrażeniu filtru. 2. Nie, użyjesz =, aby wyszukać pojedynczy element w relacji M2M/FK. Zobacz [wyszukiwania, które obejmują relacje] (https://docs.djangoproject.com/en/1.3/topics/db/queries/#lookups-that-span-relationships). –

+0

@Finglish można uzyskać dostęp do relacji z obu stron. Zobacz link, który dałem agf. –