Django 2 url路径匹配负值

Posted

技术标签:

【中文标题】Django 2 url路径匹配负值【英文标题】:Django 2 url path matching negative value 【发布时间】:2018-07-29 19:04:51 【问题描述】:

在 Django 2 中建议使用 path() 而不是 url()

path('account/<int:code>/', views.account_code, name='account-code')

这看起来不错,匹配 url 模式效果很好

/account/23/
/account/3000/

但是,这个问题是我也希望它匹配负整数,例如

/account/-23/

请问我该如何使用 path() 来做到这一点?

【问题讨论】:

您是否尝试过对您的 URL 进行 URL 编码? similar problem 为此提交了错误报告 - code.djangoproject.com/ticket/29143。抄送@neverwalkaloner 显然,这是一个intended behavior“匹配零或任何正整数。返回一个int。” 根据定义整数值也包括负值。我不知道为什么这应该确保绝对整数行为 【参考方案1】:

你可以写custom路径转换器:

class NegativeIntConverter:
    regex = '-?\d+'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return '%d' % value

在 urls.py 中:

from django.urls import register_converter, path

from . import converters, views

register_converter(converters.NegativeIntConverter, 'negint')

urlpatterns = [
    path('account/<negint:code>/', views.account_code),
    ...
]

【讨论】:

【参考方案2】:

我懒得做一个花哨的路径转换器,所以我只是将它捕获为一个字符串并将其转换为视图中的整数(通过一些基本的完整性检查以确保该值可以正确地转换为整数):

urls.py

urlpatterns = [
    path('account/<str:code>/', views.account_code),
    ...
]

views.py(新)

基于功能的视图 (FBV) 示例:

from django.http import HttpResponseNotFound

def your_view(request, code):
    try:
        code = int(self.kwargs['code'])
    except ValueError:
        # produces HTTP status code 404: Not Found
        return HttpResponseNotFound(
            "'code' must be convertible to an integer.")

基于类的视图 (CBV) 示例:

from django.http import HttpResponseNotFound
from django.views.generic import TemplateView

class CodeView(TemplateView):

    def dispatch(self, request, *args, **kwargs):
        try:
            code = int(self.kwargs['code'])
        except ValueError:
            # produces HTTP status code 404: Not Found
            return HttpResponseNotFound(
                "'code' must be convertible to an integer.")
        return super().dispatch(request, *args, **kwargs)

如果您希望用户知道发生了客户端错误,您可以将 HttpResponseNotFound 替换为 HttpResponseBadRequest,这将给出 HTTP 状态代码 400(错误请求)


编辑:下面的版本会产生一个服务器错误 HTTP 响应代码,可能是不可取的(可能会出现在错误日志等中)

views.py(旧的,由于历史原因留在这里)

try:
    code = int(self.kwargs['code'])
except ValueError:
    # produces HTTP status code 500: Internal Server Error
    raise ValueError("'code' must be convertible to an integer.")

【讨论】:

简单有效!

以上是关于Django 2 url路径匹配负值的主要内容,如果未能解决你的问题,请参考以下文章

Django路由层

django使用url路径组合搜索

Django之路由系统

django 2.2.5 URL 路径中的 URL 正则表达式

django的url分发封装

django搭建完毕运行显示hello django