2015-02-02 1 views
0

Я пытаюсь портировать приложение с Django 1.4.15 -> 1.7.3Изменения «» QuerySet из Django 1.4 до 1.7

Я пришел к проблеме, где приложения есть метод в моделях .py

def is_votable(self, user): 
     ''' 
     Decides if the user can vote for him/herself or not 
     ''' 
     if self.rated_by.all().__contains__(user): 
      return False 
     return True 

у меня проблема находится на этой линии:

if self.rated_by.all().__contains__(user): 

который создает ошибку:

'QuerySet' object has no attribute '__contains__' 

Я, наверное, слепой, поскольку не вижу, где __contains__ устарел в Django. Любая помощь глубоко оценена. Также просто спросите, нужна ли вам дополнительная информация.

ответ

3

Вы должны почти никогда не вызывать методы двойного подчеркивания, такие как __contains__ в вашем коде. Почти во всех случаях использовать in оператор:

if user in self.rated_by.all(): 

Обратите внимание, что это является Python для всей вещи: например, вместо вызова mylist.__length__() вы могли бы сделать len(mylist), вместо того, чтобы делать myobj.__unicode__() вы делаете unicode(myobj) и т.д.

в данном обстоятельстве, хотя, вы можете также найти его более эффективным, чтобы сделать запрос:

if self.rated_by.filter(user_id=user.id).exists(): 

Это попадает в базу данных для одного EXISTS запроса. Если вы не используете запрос rated_by в другом месте этого конкретного объекта, это определенно будет более эффективным, чем запрос all() и проверка членства.

+0

Спасибо, что помогли. Также объясняется много. Большое вам спасибо за ваш ответ. – user123577

+1

Не забудьте принять ответ, чтобы указать будущим искателям, что он решил проблему. –

1

Метод __contains__ был removed, когда итерация запроса была changed, чтобы больше не создавать модели в кусках.

В то время как in вызывает метод __contains__, если он существует, он не должен существовать для оператора in для работы. На самом деле это работает, если вы предоставляете только метод __iter__, который возвращает итерируемый. Поскольку рефакторинг больше не нуждался в какой-либо специальной логике, а __contains__ был частной функцией, он был удален без каких-либо конкретных заметок в примечаниях к выпуску. Это хорошая причина сделать то, что предложил Даниэль, и всегда использовать публичный API, т. Е. Оператор in.