Подтвердить что ты не робот

Использовать метод get_queryset() или установить переменную queryset?

Эти два фрагмента кода идентичны при первом румянце:

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_poll_list'
    queryset = Poll.active.order_by('-pub_date')[:5]

и

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_poll_list'

    def get_queryset(self):
        return Poll.active.order_by('-pub_date')[:5]

Есть ли разница между ними? И если это:

Какой подход лучше? Или при установке переменной queryset лучше, чем переопределить метод get_queryset? И наоборот.

4b9b3361

Ответ 1

В вашем примере переопределение queryset и get_queryset имеет тот же эффект. Я бы немного одобрил настройку queryset, потому что он менее подробный.

Когда вы устанавливаете queryset, набор запросов создается только один раз, когда вы запускаете свой сервер. С другой стороны, метод get_queryset вызывается для каждого запроса.

Это означает, что get_queryset полезен, если вы хотите динамически настраивать запрос. Например, вы можете вернуть объекты, принадлежащие текущему пользователю:

class IndexView(generic.ListView):
    def get_queryset(self):
        """Returns Polls that belong to the current user"""
        return Poll.active.filter(user=self.request.user).order_by('-pub_date')[:5]

Еще один пример, когда get_queryset полезен, - это когда вы хотите отфильтровать на основе вызываемого, например, возвратить сегодня опросы:

class IndexView(generic.ListView):
    def get_queryset(self):
        """Returns Polls that were created today"""
        return Poll.active.filter(pub_date=date.today())

Если вы попытались сделать то же самое, установив queryset, тогда date.today() будет вызываться только один раз, когда будет загружено представление, и представление через некоторое время отобразит неверные результаты.

class IndexView(generic.ListView):
    # don't do this!
    queryset = Poll.active.filter(pub_date=date.today())

Ответ 2

Другие ответы пропустили важное значение того факта, что атрибут queryset оценивается при запуске процесса. Поскольку вы не просто создаете набор запросов, вы его нарезаете, запрос будет оцениваться в этот момент. Это означает, что в этот момент вы получите только 5 лучших опросов, и они не будут обновляться, даже если вы создадите еще один, до тех пор, пока процесс не будет перезапущен.

Это точно, когда вы должны использовать get_queryset().

Ответ 3

Атрибут queryset используется внутренне, всегда используйте метод (вам часто приходится выполнять пользовательские запросы на основе запросов или сеансовых варов, например)

Ответ 4

Модель и набор запросов очень похожи, но значение запроса, если оно задано, переопределяет значение модели.

Модель - это тип объекта, отображаемого этим представлением.

Overriding get_queryset управляет тем, что конкретные экземпляры отображает это представление (например: последние 5 экземпляров)

Из документации Django:

Модель:

Модель, на которую будет отображаться этот вид. Задание модели = Foo фактически совпадает с указанием queryset = Foo.objects.all(), где объекты означают менеджер по умолчанию Foos.

QuerySet:

QuerySet, представляющий объекты. Если предоставлено, значение queryset заменяет значение, предоставленное для модели.

get_queryset:

get_queryset() Возвращает набор запросов, который будет использоваться для извлечения объекта, который будет отображаться в этом представлении. По умолчанию get_queryset() возвращает значение атрибута queryset, если он установлен, в противном случае он строит QuerySet, вызывая метод all() в атрибуте по умолчанию для атрибутов модели.