Evgenii Legotckoi
Мамыр 15, 2018, 8:07 Т.Қ.

Джанго - үзінді 001. get_object_or_none

Мазмұны

Джанго таңбашаларында get_object_or_404 функциясы бар, бірақ get_object_or_none функциясы жоқ, ол біз 404 қатесін бірден көтергіміз келмегенде пайдалы болуы мүмкін, бірақ сонымен бірге бізде кейбір әрекеттерді орындау қажет. объект дерекқорда жоқ болса.

Мен Интернетте талқылауды таптым, онда әзірлеушілер мұндай функционалдылықты әзірлеушінің жобасының ішінде дейін функциясы ретінде оңай енгізуге болатындығы және оны негізгі кодта енгізу қажет еместігі туралы жазылудан бас тартты.


Сайттағы тегтерді іздеу үшін маған ұқсас функция қажет болды.

Сондықтан мен оны төте жол ретінде сайттың өзегіне қостым.

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 []

Осы тақырып бойынша ұсынылатын мақалалар

Мақала бойынша сұралады0сұрақтар(лар)

3

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

ПК
  • Мамыр 19, 2018, 5:11 Т.Қ.
Тоже искал подобную функцию, чтобы не обрабатывать каждый раз исключения. И нашёл на so совет использовать вместо неё метод менеджера first(), который возвращает None при пустом queryset. Т.е можно было так
tag = Tag.objects.first()
if tag:
  return tag
return []
Evgenii Legotckoi
  • Мамыр 19, 2018, 6:25 Т.Қ.

В вашем случае происходит подмена сущностей. Вместо того, чтобы взять один конкретный объект, вы забираете queryset а потом берёте из него первый объект. Нехорошо будет, если queryset в каком-то случае вернёт два объекта или более. Проблема в том, что вы не узнаете об этой ошибке никак, а это нарушит логику работы приложения с последствиями в будущем. Мой вариант решения хотя бы порушит приложение и даст знать что существует два одинаковых по каким-то параметрам объекта, и нужно будет принимать меры для исправления.

Лично мне не нравится ваше решение.
ПК
  • Мамыр 19, 2018, 6:34 Т.Қ.

Согласен с тем что ваше решение более очевидно при чтении кода. first() же здесь применяется не совсем по назначению. А с последствиями "моего" решения не согласен. Метод вернёт только один объект, если он существует, или None. А целостность базы данных лучше, наверно, проверять на этапе добавления записи, а не при доступе к ней. В остальном поведение идентично вашему методу.

Evgenii Legotckoi
  • Мамыр 19, 2018, 6:44 Т.Қ.

А вы гарантируете, что метод first вернёт нужный объект, если в таблице две похожих записи? Этого никто не гарантирует. Может возникнуть неопределённое поведение приложения, если запись не так, что требовалась. А насчёт целостности базы данных перед добавлением я согласен, хотя по идее уровни блокировки на чтение записи в самой базе данных должны разруливать такую ситуацию, но у меня случалась подобная ситуация. Увы..

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз