2012-05-03 27 views
5

mam tę długą oświadczenie queryset na widokuRe oceniać zapytania django po zmianach dokonanych na bazie

contributions = user_profile.contributions_chosen.all()\ 
    .filter(payed=False).filter(belongs_to=concert)\ 
    .filter(contribution_def__left__gt=0)\ 
    .filter(contribution_def__type_of='ticket') 

że używam w moim szablonu

context['contributions'] = contributions 

A później na tym widoku dokonać zmian (dodaj lub usuń rekord) do tabeli contributions_chosen, a jeśli chcę, aby mój kontekst ["wkład"] został zaktualizowany, muszę zażądać bazy danych z tym samym długotrwałym zapytaniem.

contributions = user_profile.contributions_chosen.all()\ 
.filter(payed=False).filter(belongs_to=concert)\ 
.filter(contribution_def__left__gt=0)\ 
.filter(contribution_def__type_of='ticket') 

A potem znowu aktualizować mój kontekst

context['contributions'] = contributions 

więc zastanawiałem się, czy tam jakiś sposób mogę uniknąć powtarzania mój własny, do przewartościowania składki więc faktycznie odzwierciedla rzeczywistych danych w bazie danych. Najlepiej byłoby zmodyfikować składki zestawu zapytań, a ich wartości zostałyby zaktualizowane, a jednocześnie baza danych odzwierciedliłaby te zmiany, ale nie wiem, jak to zrobić.

UPDATE: To co robię pomiędzy dwoma kontekście [ 'wkład'] = wpłaty

dodać nowy obiekt przyczynek do contributions_chosen (jest to relacja M2M),

contribution = Contribution.objects.create(kwarg=something,kwarg2=somethingelse) 
user_profile.contributions_chosen.add(contribution) 
contribution.save() 
user_profile.save() 

w niektórych przypadkach usunąć obiekt wkład wpis = user_profile.contributions_chosen.get (id = 1) user_profile.contributions_chosen.get (id = request.POST [ 'con contribution.delete()

Jak widać, modyfikuję tabelę contributions_chosen, więc muszę ponownie wystawić zapytanie i zaktualizować kontekst. Co robię źle?

UPDATE Po obejrzeniu swoje uwagi na temat oceny, uświadamiam sobie zrobić eval w queryset zrobić len (składki) pomiędzy kontekście [ „wkład”] i który wydaje się być problemem. Po prostu przeniesię to po operacji bazy danych i to wszystko, dzięki koleś.

+0

Wydaje się, że nie oceniano queryset 'contributions', więc nie ma potrzeby martwić się o aktualizację, bo to jeszcze nie pobranych danych z DB. 'QuerySet' jest leniwy, dlatego nie ma nic wspólnego z wierszami DB, dopóki nie został oceniony. – okm

Odpowiedz

2

Nie wiem, jak można uniknąć ponownej oceny zapytania, ale jednym ze sposobów na zapisanie kilku powtarzających się stwierdzeń w kodzie byłoby utworzenie dyktowania przy użyciu wszystkich tych filtrów i określenie argumentów jako dict: filter:

query_args = dict(
    payed=False, 
    belongs_to=concert, 
    contribution_def__left__gt=0, 
    contribution_def__type_of='ticket', 
) 

a następnie

contributions = user_profile.contributions_chosen.filter(**query_args) 

To tylko usuwa pewne powtarzające się kod, ale nie rozwiązuje powtarzającego zapytania. Jeśli trzeba zmienić args, po prostu obsłużyć query_args jako zwykły Python dict, jest to jeden po wszystkich :)

+1

W kodzie, który podaje, i tak nie ocenia zapytania. Zapytanie zostanie ocenione, gdy wykona iterację nad nim w szablonie lub gdy wykona inne czynności, które wyzwalają ocenę zapytania, co udokumentowano na stronie https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets -to-evaluated –

3

aktualizacji wydaje nie oceniano queryset contributions, więc nie ma potrzeby martwić się o aktualizacji, ponieważ nadal nie pobrał danych z DB.

Czy możesz wpisać kod między dwiema liniami context['contributions'] = contributions? Zwykle przed oceną zestawu zapytań contributions (na przykład przez iterowanie go lub wywoływanie jego numeru __len__()), nie zawiera on niczego odczytywanego z DB, dlatego nie trzeba jej aktualizować.

Aby ponownie ocenić queryset, można

# make a clone 
contribution._clone() 
# or any op that makes clone, for example 
contribution.filter() 

# or clear its cache 
contribution._result_cache = None 

# you could even directly add new item to contribution._result_cache, 
# but its could cause unexpected behavior w/o carefulness 
+1

Również "contribution.all()" –

+0

Dokumenty specjalnie [sugerują użycie 'all()'] (https://docs.djangoproject.com/en/1.11/ref/models/querysets/#all) w tym celu. –

Powiązane problemy