使用无效的 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']
    ...