2012-05-03 2 views
5

Я получил это длинное заявление QuerySet на представленииRe оценить Джанго запрос после изменений, сделанных в базе данных

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') 

, что я использую в моем шаблоне

context['contributions'] = contributions 

А потом на этой точке зрения я внести изменения (добавьте или удалите запись) в таблицу contrib_chosen, и если я хочу обновить свой контекст [«взносов»], мне нужно запросить базу данных с тем же самым запросом длины.

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') 

И затем снова обновить мой контекст

context['contributions'] = contributions 

Так что мне было интересно, если Theres каким-либо образом я могу избежать повторения мой сам, переоценивать вклад, так что на самом деле отражает реальные данные по базе данных. В идеале я бы изменил вкладки запроса, и его значения будут обновлены, и в то же время база данных будет отражать эти изменения, но я не знаю, как это сделать.

UPDATE: Это то, что я делать между двумя контексте [ «вклад»] = взносы

добавить новый объект вклад в contributions_chosen (это M2M отношение),

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

А в некоторых случаях я удалить объект вклад вклад = user_profile.contributions_chosen.get (ID = 1) user_profile.contributions_chosen.get (ID = request.POST [ 'мошенника contribution.delete()

Как вы можете видеть, я изменяю таблицу contrib_chosen, поэтому мне нужно переиздать запрос и обновить контекст. Что я делаю неправильно?

UPDATE После просмотра ваших комментариев об оценке, я понимаю, что я делаю eval запрос, я делаю len (вклад) между контекстом ['contrib'] и это кажется проблемой. Я просто перевешу его после операций с базой данных, и это так, спасибо парню.

+0

Кажется, вы не оценили QuerySet 'contributions', таким образом, нет необходимости беспокоиться об обновлении, потому что она до сих пор не неправдоподобные данные из БД. 'QuerySet' является ленивым, поэтому он не имеет ничего общего с строками DB, пока не будет оценен. – okm

ответ

2

Я не знаю, как можно избежать повторной оценки запроса, но одним из способов сохранить некоторые повторяющиеся утверждения в вашем коде было бы создание dict со всеми этими фильтрами и указание аргументов filter как dict:

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

, а затем

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

Это просто удаляет некоторые повторяющийся код, но не решает повторный запрос. Если вам нужно изменить арг, просто обрабатывать query_args как обычный Dict Python, это один в конце концов :)

+1

В коде, который он предоставляет, он все равно не оценивает запрос. Запрос оценивается, когда он повторяет его в шаблоне или когда он выполняет другие действия, которые инициируют оценку запроса, как описано в https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets -are-rated –

3

обновление Кажется, вы не оценили QuerySet contributions, таким образом, нет необходимости беспокоиться о обновляя его, поскольку он все еще не извлекал данные из БД.

Можете ли вы отправить код между двумя линиями context['contributions'] = contributions? Обычно, прежде чем вы оцениваете запрос contributions (например, итерацией по нему или вызовом его __len__()), он не содержит ничего, что читается из БД, поэтому вам не нужно указывать его содержимое.

Чтобы повторно оценить QuerySet, вы могли бы

# 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

Также 'contrib.all()' –

+0

Документы специально [предлагают использовать 'all()'] (https://docs.djangoproject.com/en/1.11/ref/models/querysets/#all) для этой цели. –

Смежные вопросы