Django: когда использовать QuerySet Нет
Просто наткнулся на это в django docs
Вызов none() приведет к созданию набора запросов, который никогда не возвращает никаких объектов и при доступе к результатам запрос не будет выполняться. Нет qs.none() queryset - это экземпляр пакета EmptyQuerySet.
Я создаю много приложений CRUD (сюрприз), и я не могу представить себе ситуацию, когда мне нужно будет использовать none()
.
Почему нужно возвращать EmptyQuerySet?
Ответы
Ответ 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", что является беспорядочным).