以下是示例代码:
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 我有特殊的逻辑来处理实例,无论是否。
答案 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)
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页面。