【问题标题】:Django - Redirect uppercase urls to lowercaseDjango - 将大写的网址重定向到小写
【发布时间】:2020-08-19 23:53:52
【问题描述】:

在我的 Django 应用程序中,我有很多网址,包括 /(?P<project_name>[_\w]+)/project_name 由用户定义,是Project 模型的属性。

我在project_name 上添加了一个验证器来检查它是否为小写。 所以新名字都是小写的,但一些旧名字包括大写字符。

我想将所有存储的名称更改为小写,但同时,我不希望用户在尝试访问包含大写字符的旧项目名称的 URL 之一时出错。 由于我有很多 url 和很多视图,我不想手动更新每个 .lower() project_name

有没有办法将包括/<project_NAME>/在内的所有网址重定向到/<project_name>/

【问题讨论】:

  • 为什么project_names 在第一种情况下是大写的?通常,为此使用slug
  • 嗯,这是一个错误……我现在想更正一下。
  • 我认为将SlugFields 添加到您的模型中可能会更容易。特别是因为 DetailViews 和 UpdateViews 支持 slug(它们会自动过滤)。此外,slug 不仅是小写字母,它还删除了变音符号和其他在 URL 中引入百分比编码的字符,因此它会使 URL 更“干净”。
  • 编写一个自定义中间件来检查 URL 并进行重定向。
  • @KevinChristopherHenry 您能否详细说明一下如何使用中间件来完成?

标签: django url


【解决方案1】:

装饰器的hacky方式

您可以为所有使用project_name 的视图创建一个装饰器:

def project_lowercase(_func=None):
    def checkLowercase(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            request = args[0]
            project_name = args[1]
            if not project_name.islower():
                return HttpResponseRedirect(reverse(your_url_name, kwargs{'project_name' = project_name.lower()))
            return func(*args, **kwargs)
        return wrapper
    return checkLowercase(_func)

your_url_name替换为您命名的url路由,然后导入函数并在每个视图函数上方添加装饰器:

@project_lowercase
def view_project(request, project_name):
    # ...
    return "Hello World!"

蛞蝓会更好

或者按照 cmets 中的建议和更好的解决方案,您应该使用 slug 来存储项目的 url,查看 here 以了解如何将它们添加到您的模型中并生成 slug。

要移动现有数据以使用 slug 或只是更新项目名称,您可以创建一个 data migration 来更改数据库中的现有数据。

【讨论】:

  • 由于我有很多视图,我想避免更改每个视图。但是按照您的建议使用装饰器会为每个装饰器添加最小的更改,因此不会那么烦人!
【解决方案2】:

我建议的第一个选项是避免使用正则表达式,将urlpatterns 切换到path 并使用custom url converter 作为项目名称。

如果您想继续使用正则表达式,您可以将模式限制为只接受小写项目名称/(?P<project_name>[_a-z0-9]+)/。之后添加 url 模式,它(实际上)与您当前的 /(?P<project_name>\w+)/ 相同(注意缺少 _ - \w 已经包含该模式)以匹配所有项目名称,包括旧项目名称,该模式的视图将使用小写 project_name 重定向到您的第一个视图。

【讨论】:

  • path 似乎确实是一个更好的解决方案!第二个选项是我想过的,但我想避免重复所有的网址。
猜你喜欢
  • 1970-01-01
  • 2014-10-02
  • 2014-06-08
  • 2016-05-23
  • 1970-01-01
  • 2010-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多