- 1. shortcuts.py
- 2. Пример
В шорткатах Django есть функция get_object_or_404 , но при этом нет функции get_object_or_none , которая может быть полезна в том случае, когда мы не хотим вызывать сразу ошибку 404, но при этом нам необходимо выполнить какие либо действия в том случае, если объект не существует в базе данных.
Удалось найти обсуждение в интернете, где разработчики отписались, что подобный функционал может быть легко внедрён в качесте until функции в рамках проекта разработчика и внедрять его в основной код не требуется.
Подобный функционал мне понадобился для поиска тегов на сайте.
Поэтому я его добавил в ядро сайта в качестве шортката.
shortcuts.py
# -*- coding: utf-8 -*- def get_object_or_none(klass, *args, **kwargs): try: return klass._default_manager.get(*args, **kwargs) except klass.DoesNotExist: return None
Пример
def get_queryset(self, **kwargs): q = self.request.GET.get('q') tag = get_object_or_none(Tag, name=q) if tag: return TaggedItem.objects.all().filter(tag=tag) return []
В вашем случае происходит подмена сущностей. Вместо того, чтобы взять один конкретный объект, вы забираете queryset а потом берёте из него первый объект. Нехорошо будет, если queryset в каком-то случае вернёт два объекта или более. Проблема в том, что вы не узнаете об этой ошибке никак, а это нарушит логику работы приложения с последствиями в будущем. Мой вариант решения хотя бы порушит приложение и даст знать что существует два одинаковых по каким-то параметрам объекта, и нужно будет принимать меры для исправления.
Согласен с тем что ваше решение более очевидно при чтении кода. first() же здесь применяется не совсем по назначению. А с последствиями "моего" решения не согласен. Метод вернёт только один объект, если он существует, или None. А целостность базы данных лучше, наверно, проверять на этапе добавления записи, а не при доступе к ней. В остальном поведение идентично вашему методу.
А вы гарантируете, что метод first вернёт нужный объект, если в таблице две похожих записи? Этого никто не гарантирует. Может возникнуть неопределённое поведение приложения, если запись не так, что требовалась. А насчёт целостности базы данных перед добавлением я согласен, хотя по идее уровни блокировки на чтение записи в самой базе данных должны разруливать такую ситуацию, но у меня случалась подобная ситуация. Увы..