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

Django: когда использовать QuerySet Нет

Просто наткнулся на это в django docs

Вызов none() приведет к созданию набора запросов, который никогда не возвращает никаких объектов и при доступе к результатам запрос не будет выполняться. Нет qs.none() queryset - это экземпляр пакета EmptyQuerySet.

Я создаю много приложений CRUD (сюрприз), и я не могу представить себе ситуацию, когда мне нужно будет использовать none().

Почему нужно возвращать EmptyQuerySet?

4b9b3361

Ответ 1

Обычно в тех случаях, когда вам нужно предоставить QuerySet, но его не следует указывать - например, вызов метода или предоставление шаблону.

Преимущество заключается в том, что вы знаете, что результата не будет (или не хотите результата), и вам все еще нужен один, none() не попадет в базу данных.

Для нереалистичного примера, скажем, у вас есть API, где вы можете запросить свои разрешения. Если учетная запись не подтверждена, поскольку у вас уже есть объект Account, и вы можете видеть, что account.is_activated is False, вы можете пропустить проверку базы данных для разрешений, просто используя Permission.objects.none()

Ответ 2

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

def get_me_queryset(conditionA, conditionB, conditionC):
    queryset = Model.objects.none()

    if conditionA:
        queryset |= some_complex_computation(conditionA)
    elif conditionB:
        queryset |= some_complex_computation(conditionB)

    if conditionC:
        queryset |= some_simple_computation(conditionC)

    return queryset

get_me_queryset должен почти всегда возвращать экземпляр django.db.models.query.QuerySet (потому что хорошее программирование), а не None или [], иначе это вызовет головную боль позже..

Таким образом, даже если ни одно из условий не True, ваш код все равно останется без изменений. Нет больше проверки типа

Для тех, кто не понимает | Использование оператора здесь:

queryset |= queryset2

Это переводится как:

queryset = queryset + queryset

Ответ 3

другое использование queryset.none - это когда вы не знаете, будут ли объекты, но не хотят поднять ошибку.

Пример:

class DummyMixin(object):

    def get_context_data(self,**kwargs):
        """ Return all the pks of objects into the context """

        context = super(DummyMixin, self).get_context_data(**kwargs)

        objects_pks = context.get(
            "object_list",
            Mymodel.objects.none()
        ).values_list("pk", flat=True)

        context["objects_pks"] = objects_pks

Ответ 4

Полезно видеть, где qs.none() используется в других примерах в документации Django. Например, при инициализации модельного набора форм с использованием набора запросов, если вы хотите, чтобы результирующий набор форм был пустым, приведенный пример:

formset = AuthorFormSet(queryset=Author.objects.none())

Ответ 5

Еще один хороший вариант использования для этого, если какой-либо вызывающий метод хочет вызвать .values_list() или аналогичный по результатам. Если метод вернул None, вы получите ошибку вроде

AttributeError: 'list' object has no attribute 'values_list'

Но если ваше предложение возвращает MyModel.objects.none() вместо None, вызывающий код будет счастлив, поскольку возвращаемые данные - это пустой набор запросов, а не объект None.

Другой способ выразить это в том, что он позволяет вам не смешивать возвращаемые типы (например, "эта функция возвращает QuerySet или None", что является беспорядочным).