在 Django URLField 中允许空方案的最干净的方法
Cleanest Way to Allow Empty Scheme in Django URLField
我正在使用 Django 2.0 并试图让用户在 Django ModelForm 中输入 link 到他们的网站。我想让我的 URLField 验证 urls,即使它们没有方案前缀。
我已阅读此解决方案:。我想知道是否有一种方法可以在不在 RegexValidator 中编写我自己的自定义正则表达式的情况下实现这一目标。重复 URLValidator.
中内置的所有正则表达式逻辑似乎不是一个非常枯燥的解决方案
我想做如下的事情:
website = models.CharField(max_length=400, blank=True, null=True, validators=[URLValidator(schemes=['', 'http', 'https', 'ftp', 'ftps'])])
这显然行不通,因为 URLValidator 的调用方法根据给定方案进行验证。
def __call__(self, value):
# Check first if the scheme is valid
scheme = value.split('://')[0].lower()
if scheme not in self.schemes:
raise ValidationError(self.message, code=self.code)
向方案列表添加空字符串不起作用,因为以这种方式拆分 url returns 整个 URL(因为用户通常不包括:/ / 如果该用户不包含方案前缀)。
现在,我 可以 子类 URLField 并覆盖整个调用方法,以改变它处理方案的方式,但调用方法包括所有正则表达式,所以这似乎只是将 URLField 正则表达式复制到我自己的 RegexValidator 中。
是否有更清洁或更 "Djangonic" 的方法来实现此目的?
您可以在调用 super()
之前将 URLValidator
子类化,并使用 http://
作为无方案值的前缀。这避免了 URLValidator
.
的任何重复代码
from django.core.validators import URLValidator
class OptionalSchemeURLValidator(URLValidator):
def __call__(self, value):
if '://' not in value:
# Validate as if it were http://
value = 'http://' + value
super(OptionalSchemeURLValidator, self).__call__(value)
我正在使用 Django 2.0 并试图让用户在 Django ModelForm 中输入 link 到他们的网站。我想让我的 URLField 验证 urls,即使它们没有方案前缀。
我已阅读此解决方案:。我想知道是否有一种方法可以在不在 RegexValidator 中编写我自己的自定义正则表达式的情况下实现这一目标。重复 URLValidator.
中内置的所有正则表达式逻辑似乎不是一个非常枯燥的解决方案我想做如下的事情:
website = models.CharField(max_length=400, blank=True, null=True, validators=[URLValidator(schemes=['', 'http', 'https', 'ftp', 'ftps'])])
这显然行不通,因为 URLValidator 的调用方法根据给定方案进行验证。
def __call__(self, value):
# Check first if the scheme is valid
scheme = value.split('://')[0].lower()
if scheme not in self.schemes:
raise ValidationError(self.message, code=self.code)
向方案列表添加空字符串不起作用,因为以这种方式拆分 url returns 整个 URL(因为用户通常不包括:/ / 如果该用户不包含方案前缀)。
现在,我 可以 子类 URLField 并覆盖整个调用方法,以改变它处理方案的方式,但调用方法包括所有正则表达式,所以这似乎只是将 URLField 正则表达式复制到我自己的 RegexValidator 中。
是否有更清洁或更 "Djangonic" 的方法来实现此目的?
您可以在调用 super()
之前将 URLValidator
子类化,并使用 http://
作为无方案值的前缀。这避免了 URLValidator
.
from django.core.validators import URLValidator
class OptionalSchemeURLValidator(URLValidator):
def __call__(self, value):
if '://' not in value:
# Validate as if it were http://
value = 'http://' + value
super(OptionalSchemeURLValidator, self).__call__(value)