我正在使用Django 2.0,并试图允许用户在Django ModelForm中输入指向其网站的链接。我想让我的URLField验证url,即使它们没有方案前缀。

我已经阅读了以下解决方案:django urlfield http prefix。我想知道是否有一种无需在RegexValidator中编写我自己的自定义regex的方法。重复内置在URLValidator中的所有正则表达式逻辑似乎不是一个非常干燥的解决方案。

我想做类似下面的事情:

website = models.CharField(max_length=400, blank=True, null=True, validators=[URLValidator(schemes=['', 'http', 'https', 'ftp', 'ftps'])])

由于URLValidator的call方法针对给定方案进行验证的方式,因此这显然不起作用。
    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会返回整个URL(因为该用户通常不包含方案前缀,因此该用户通常不包含://)。

现在,我可以子类化URLField并覆盖整个调用方法,以更改其处理方案的方式,但是该调用方法包括所有正则表达式,因此,这似乎比将URLField regex复制到我的目录中更简单。自己的RegexValidator。

有没有更清洁或更“Djangonic”的方式来实现这一目标?

最佳答案

您可以在调用URLValidator之前对http://进行子类化,并使用super()前缀无方案值。这样可以避免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 - 在Django URLField中允许空方案的最干净方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49983328/

10-13 05:37