使用URLField保存对象的正确方法

时间:2020-10-27 13:38:44

标签: django django-models

我有一个模型类KeyWord

class KeyWord(models.Model):
    keyword = models.CharField(verbose_name="Topic",max_length=50)
    link = models.URLField(verbose_name = "Next Best Action", max_length=500,null=True)

    def __str__(self):
        return self.keyword

如果我创建这样的对象:

KeyWord.objects.create(keyword="hello",link="world")

理想情况下会引发错误,因为我正在向link的{​​{1}}字段分配普通文本,但是对象创建成功?

我应该使用哪个字段或应该怎么做才能保存具有有效链接的对象?

1 个答案:

答案 0 :(得分:2)

前提条件:仅当您调用full_clean()时,才会进行模型验证。如果您使用ModelForm,则在调用form.save()时会为您完成,但是如果您上传具有自定义视图逻辑的Excel文件,则需要进行do this yourself

验证模型涉及三个步骤:

  • 验证模型字段-Model.clean_fields()
  • 验证模型整体-Model.clean()
  • 验证字段唯一性-Model.validate_unique()

这三个步骤都是在调用模型的full_clean()方法时执行的。

正如我之前所说,无法告诉URLField要求fully qualified URLs。为此,您需要覆盖URLValidator。

它的正则表达式非常讨厌,您可能不想弄乱它,所以一种替代方法是添加其他验证器:

from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible

@deconstructible
class RequireHttpOrHttpsUrl:
    def __call__(self, value):
        if not value.startswith("http://") and not value.startswith("https://"):
            raise ValidationError('Please provide a http or https resource')

class KeyWord(models.Model):
    keyword = models.CharField(verbose_name="Topic",max_length=50)
    link = models.URLField(
        verbose_name = "Next Best Action",
        max_length=500, null=True,
        validators=[RequireHttpOrHttpsUrl()]
    )

    def __str__(self):
        return self.keyword

按照注释中的建议使用urllib.parse():

我强烈建议您使用URLValidator来解决urllib.parse()更好的地方。 URLValidator拒绝:

  • http://
  • http:// bla
  • https:// bla

接受:

因此,我找不到添加另一个解析器的好处。