Каков наилучший способ обработки Django objects.get? - PullRequest
40 голосов
/ 04 декабря 2010

Всякий раз, когда я делаю это:

thepost = Content.objects.get(name="test")

Всегда выдает ошибку, когда ничего не найдено.Как мне с этим справиться?

Ответы [ 7 ]

69 голосов
/ 04 декабря 2010
try:
    thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
    thepost = None

Использовать модель DoesNotExist исключение

23 голосов
/ 04 декабря 2010

Часто более полезно использовать функцию быстрого вызова Django get_object_or_404 вместо API напрямую:

from django.shortcuts import get_object_or_404

thepost = get_object_or_404(Content, name='test')

Совершенно очевидно, что это приведет к ошибке 404, еслиобъект не может быть найден, и ваш код продолжит работу, если он будет успешным.

15 голосов
/ 04 декабря 2010

Вы также можете поймать универсальный DoesNotExist.Согласно документам на http://docs.djangoproject.com/en/dev/ref/models/querysets/

from django.core.exceptions import ObjectDoesNotExist
try:
    e = Entry.objects.get(id=3)
    b = Blog.objects.get(id=1)
except ObjectDoesNotExist:
    print "Either the entry or blog doesn't exist."
9 голосов
/ 16 сентября 2014

Другой способ написания:

try:
    thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
    thepost = None

это просто:

thepost = Content.objects.filter(name="test").first()

Обратите внимание, что они не являются строго одинаковыми. Метод менеджера get вызовет не только исключение в случае нет записи , к которой вы обращаетесь, но также и при обнаружении нескольких записей . Использование first при наличии более одной записи может привести к сбою в вашей бизнес-логике путем возврата первой записи.

7 голосов
/ 04 декабря 2010

Поймать исключение

try:
    thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
    thepost = None

в качестве альтернативы вы можете отфильтровать, который вернет пустой список, если ничего не соответствует

posts = Content.objects.filter(name="test")
if posts:
    # do something with posts[0] and see if you want to raise error if post > 1
2 голосов
/ 21 апреля 2014

Обработка исключений в разных точках в ваших представлениях может быть очень трудоемкой. А как насчет определения собственного менеджера моделей в файле models.py, например

class ContentManager(model.Manager):
    def get_nicely(self, **kwargs):
        try:
            return self.get(kwargs)
        except(KeyError, Content.DoesNotExist):
            return None

и затем включение его в класс модели содержимого

class Content(model.Model):
    ...
    objects = ContentManager()

Таким образом, это может быть легко рассмотрено в представлениях, т.е.

post = Content.objects.get_nicely(pk = 1)
if post != None:
    # Do something
else:
    # This post doesn't exist
1 голос
/ 31 января 2013

Повышение Http404 исключения прекрасно работает:

from django.http import Http404

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404
    return render_to_response('polls/detail.html', {'poll': p})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...