在Django中如何避免样板代码在视图中通过pk获取模型实例

时间:2014-03-24 14:33:18

标签: python django

以下是示例代码:

def someview(request):
    try:
        instance = SomeModel.objects.get(id=request.GET.get('id'))
    except SomeModel.DoesNotExist:
        instance = None
    except ValueError:
        # This error may occur if user manually enter invalid (non-integer)
        # id value (intentionally or not) in a browser address bar, e.g.
        # http://example.com/?id=2_foo instead of http://example.com/?id=2
        # This raises ValueError: invalid literal for int() with base 10: '2_'
        instance = None
    ...

是否有最佳实践可以通过pk获取模型实例而无需反复编写此样板代码?我应该在Django中使用一些预定义的快捷方式还是只使用自己的快捷方式?

我确信我应该使用Django的DetailView或SingleObjectMixin但奇怪的是它没有处理我的示例https://github.com/django/django/blob/master/django/views/generic/detail.py#L50中的ValueError异常
是否暗示我必须在urlconf中为pk kwarg指定正确的整数regexp?好吧,可能。但是,如果我从请求查询字符串获取pk怎么办?

UPD 我有特殊的逻辑来处理实例,无论是否。

3 个答案:

答案 0 :(得分:3)

你也可以使用专为此设计的shangcut get_object_or_404()内置的Django。如果对象不存在,该函数将引发Http404异常。如果你想获得None而不是引发异常,你可以创建一个帮助函数来轻松完成它:

def get_object_or_none(klass, *args, **kwargs):
    try:
        return get_object_or_404(klass, *args, **kwargs)
    except Http404:
        return None

希望这有帮助!

答案 1 :(得分:1)

使用django-annoying

可以简化try / except块的第一部分
from annoying.functions import get_object_or_None

instance = get_object_or_None(SomeModel, id=request.GET.get('id'))

仅供参考,您也可以从包中提取get_object_or_None(参见source)。

答案 2 :(得分:1)

有许多基于通用类的视图可能会有所帮助,在您的情况下DetailView可以正常工作。

from django.views.generic.detail import DetailView

class SomeModelDetailView(DetailView):
     model = SomeModel

您可以覆盖get_object方法来更改默认行为。

def get_object(self, queryset=None):
    return SomeModel.objects.get(pk=self.get_pk())

最后,如果object is none,你应该显示自定义404页面。