Evgenii Legotckoi
May 15, 2018, 8:07 p.m.

Django - Snippet 001. get_object_or_none

Content

In Django shortcuts there is a function get_object_or_404 , but there is no function get_object_or_none , which can be useful in the case when we do not want to cause error 404 immediately, but we need to perform some actions in case the object does not exist in the database data.

It was possible to find a discussion on the Internet, where developers wrote that such a functional can be easily implemented as a function until a function within the project of the developer and it is not required to introduce it into the main code.


I needed this functionality to search for tags on the site.

So I added it to the core of the site as a shortcut.

shortcuts.py

  1. # -*- coding: utf-8 -*-
  2.  
  3.  
  4. def get_object_or_none(klass, *args, **kwargs):
  5. try:
  6. return klass._default_manager.get(*args, **kwargs)
  7. except klass.DoesNotExist:
  8. return None

Example

  1. def get_queryset(self, **kwargs):
  2. q = self.request.GET.get('q')
  3. tag = get_object_or_none(Tag, name=q)
  4. if tag:
  5. return TaggedItem.objects.all().filter(tag=tag)
  6. return []
ПК
  • May 19, 2018, 5:11 p.m.
Тоже искал подобную функцию, чтобы не обрабатывать каждый раз исключения. И нашёл на so совет использовать вместо неё метод менеджера first(), который возвращает None при пустом queryset. Т.е можно было так
tag = Tag.objects.first()
if tag:
  return tag
return []
Evgenii Legotckoi
  • May 19, 2018, 6:25 p.m.

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

Лично мне не нравится ваше решение.
ПК
  • May 19, 2018, 6:34 p.m.

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

Evgenii Legotckoi
  • May 19, 2018, 6:44 p.m.

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

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
  • ИМ
    Nov. 22, 2024, 9:51 p.m.
    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
  • Evgenii Legotckoi
    Oct. 31, 2024, 11:37 p.m.
    Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
  • A
    Oct. 19, 2024, 5:19 p.m.
    Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html