2010-12-04 2 views
32

Всякий раз, когда я делаю это:Каков наилучший способ работы с объектами Django?

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

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

+0

См. Также [QuerySet.get] (http://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.QuerySet.get) – 2010-12-04 12:00:02

+2

Так оно и должно быть Работа. Каков твой вопрос? Как написать инструкцию `try`? – 2010-12-04 12:37:58

ответ

56
from django.core.exceptions import ObjectDoesNotExist 

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

Я пишу это из памяти, поэтому я не уверен об исключении.

+8

В этом случае исключением является `Content.DoesNotExist`, и эта структура кода полезна, если вы хотите продолжить, даже если объект не может быть найден (т. Е. Не вывести ошибку 404, как в моем примере). – 2010-12-04 11:04:55

20

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

from django.shortcuts import get_object_or_404 

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

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

7

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

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 
+0

зачем выделять пустой Queryset, когда get() будет просто создавать исключение? Первый подход try/catch намного лучше. – ppetrid 2012-11-17 01:44:45

12

Вы также можете поймать общий 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." 
0

Поднятие Http404 exception прекрасно работает:

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}) 
2

Обработка исключений в различных точках в ваших взглядах может быть действительно cumbersome..What об определении пользовательских Model Manager, в 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 
5

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

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

просто:

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

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

Смежные вопросы