使用无效的 uuid 时引发 404 而不是 500
Raise 404 instead of 500 when using an invalid uuid
我的 Document
模型中有一个 uuid 字段
如果我使用错误的 uuid get() 我的模型,我会收到错误 500。
此行抛出错误:
x = Document.objects.get(uuid=object_uuid)
我想要 404 错误而不是 500
我写了这个,但我不想把我的功能放在任何地方它太多余了(我很懒)
def is_valid_uuid_or_404(object_uuid):
try:
return uuid.UUID(object_uuid)
except ValueError:
raise Http404("Invalid uuid")
x = Document.objects.get(uuid=is_valid_uuid_or_404(object_uuid)) #Boring
有人有更好的想法吗?
编辑 1:
我在管理员的 change_view
方法中获取我的对象,我覆盖 change_view
以添加 extra_context,这遵循 django
的建议
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context["my_field"] = Document.objects.get(uuid=object_id).my_field
return super().change_view(request, object_id, form_url, extra_context=extra_context)
您可以创建一个 custom model manager,然后向其添加自定义方法
from django.db import models
class DocumentManager(models.Manager):
def get_by_uuid(self, uuid, **kwargs):
try:
return uuid.UUID(object_uuid)
except ValueError:
raise Http404("Invalid uuid")
return self.get(uuid=uuid, **kwargs)
class Document(models.Model):
objects = DocumentManager()
x = Document.objects.get_by_uuid(object_uuid)
由于您试图在模型管理中获取此对象,只需使用模型管理已经具有的 get_object
方法来获取对象,这样您就不需要处理错误和所有您需要处理的是返回 None
的方法,因为没有匹配的对象:
from django.contrib.admin.utils import unquote
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
to_field = request.POST.get('_to_field', request.GET.get('_to_field'))
object = self.get_object(request, unquote(object_id), to_field)
extra_context["my_field"] = object.my_field if object else None
return super().change_view(request, object_id, form_url, extra_context=extra_context)
一般解:
错误(无效)的 uuid 会导致此错误,这会给您 500 响应,而不是您想要的 404 响应。与其捕获此错误,不如事先执行 validation。您可能从几个地方获得了 UUID,为简单起见,我们假设您是从 url 参数或表单中获得的。这两者当然都有正确的方法来验证 UUID。
对于 url 模式,你应该使用 uuid
path converter,如果传递的 uuid 不是有效的 uuid,请求甚至不会被路由到视图,你会得到一个404:
path('some-view/<uuid:object_uuid>/', views.some_view),
下一步您应该使用 UUIDField
[Django-docs] 并使用表单清理和验证:
from django import forms
class SomeForm(forms.Form):
object_uuid = forms.UUIDField()
# In your view
def some_view(request):
...
form = SomeForm(request.POST)
if form.is_valid():
object_uuid = form.cleaned_data['object_uuid']
...
我的 Document
模型中有一个 uuid 字段
如果我使用错误的 uuid get() 我的模型,我会收到错误 500。 此行抛出错误:
x = Document.objects.get(uuid=object_uuid)
我想要 404 错误而不是 500
我写了这个,但我不想把我的功能放在任何地方它太多余了(我很懒)
def is_valid_uuid_or_404(object_uuid):
try:
return uuid.UUID(object_uuid)
except ValueError:
raise Http404("Invalid uuid")
x = Document.objects.get(uuid=is_valid_uuid_or_404(object_uuid)) #Boring
有人有更好的想法吗?
编辑 1:
我在管理员的 change_view
方法中获取我的对象,我覆盖 change_view
以添加 extra_context,这遵循 django
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context["my_field"] = Document.objects.get(uuid=object_id).my_field
return super().change_view(request, object_id, form_url, extra_context=extra_context)
您可以创建一个 custom model manager,然后向其添加自定义方法
from django.db import models
class DocumentManager(models.Manager):
def get_by_uuid(self, uuid, **kwargs):
try:
return uuid.UUID(object_uuid)
except ValueError:
raise Http404("Invalid uuid")
return self.get(uuid=uuid, **kwargs)
class Document(models.Model):
objects = DocumentManager()
x = Document.objects.get_by_uuid(object_uuid)
由于您试图在模型管理中获取此对象,只需使用模型管理已经具有的 get_object
方法来获取对象,这样您就不需要处理错误和所有您需要处理的是返回 None
的方法,因为没有匹配的对象:
from django.contrib.admin.utils import unquote
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
to_field = request.POST.get('_to_field', request.GET.get('_to_field'))
object = self.get_object(request, unquote(object_id), to_field)
extra_context["my_field"] = object.my_field if object else None
return super().change_view(request, object_id, form_url, extra_context=extra_context)
一般解:
错误(无效)的 uuid 会导致此错误,这会给您 500 响应,而不是您想要的 404 响应。与其捕获此错误,不如事先执行 validation。您可能从几个地方获得了 UUID,为简单起见,我们假设您是从 url 参数或表单中获得的。这两者当然都有正确的方法来验证 UUID。
对于 url 模式,你应该使用 uuid
path converter,如果传递的 uuid 不是有效的 uuid,请求甚至不会被路由到视图,你会得到一个404:
path('some-view/<uuid:object_uuid>/', views.some_view),
下一步您应该使用 UUIDField
[Django-docs] 并使用表单清理和验证:
from django import forms
class SomeForm(forms.Form):
object_uuid = forms.UUIDField()
# In your view
def some_view(request):
...
form = SomeForm(request.POST)
if form.is_valid():
object_uuid = form.cleaned_data['object_uuid']
...