2012-12-16 7 views
5

W jaki sposób można filtrować model na podstawie modelu, który się z nim wiąże? Przykład poniżej ... to działa, ale myślę, że to trafia do DB dwukrotnie i jest dość nieelegancki. Czy istnieje sposób, aby zrobić to bezpośrednio z zapytaniami? Może w jakiś sposób z select_related(), ale nie udało się tego wymyślić. Chcę zwrócić QuerySet z Project.Filtr zapytań Django dla powiązanych ze sobą pól

from django.db import models 

class Person(models.Model): 
    pass 

class Project(models.Model): 
    pass 

class Action(models.Model): 
    person = models.ForeignKey(Person) 
    project = models.ForeignKey(Project) 

# Better way to do this? 
def projects_by_person(person): 
    actions = Action.objects.filter(person=person) 
    project_ids = actions.values_list('project') 
    return Project.objects.filter(id__in=project_ids) 
+0

W rzeczywistości powinno to być tylko jedno trafienie w bazie danych, ponieważ filtr zostanie wykonany jako pod-zapytanie. Niemniej jednak, stosowanie Raunak sugeruje, że użycie podwójnej podkreślonej składni jest lepszym rozwiązaniem. –

+0

Dobrze wiedzieć. Łączenie powinno wykonać się nieco szybciej niż podzapytanie w (...). Dzięki! – pyrospade

Odpowiedz

9

Spróbuj tego. Nie testowałem to daj mi znać, jeśli masz jakiekolwiek problemy

#Untested Code 
Project.objects.filter(action__person = person) 
+0

Nie zdawałem sobie sprawy, że do filtrowania można użyć odpowiedniego pola. Prosty i elegancki, dzięki! – pyrospade

2

Czy to prawda, że ​​masz wiele do wielu relacji między Person i Project? Jeśli tak, możesz uprościć konfigurację w następujący sposób:

class Person(models.Model): 
    projects = models.ManyToManyField('Project') 
    name = models.CharField(max_length=100)  # just an example 

class Project(models.Model): 
    # ... some fields here ... 

Możesz wtedy np. wydaj następujące zapytanie, aby wszystkie projekty z ludźmi, którzy są powołani John:

Project.objects.filter(person_set__name="John") 

Wykorzystanie select_related() może przyspieszyć wyszukiwanie trochę gdy masz wiele pytań, które następują relacje między różnymi tabelami bazy danych, ale don nie potrzebuję tego, aby osiągnąć to, czego chcesz.

+0

Dzięki, ale model Person nie jest tak naprawdę związany z projektami. Modele te są dość wymyślne, po prostu dając przykład bez zestawu niepowiązanych ze sobą elementów. – pyrospade