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

Django 使用URLField保存对象的正确方法,django,django-models,Django,Django Models,我有一个模型类关键字 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): ret

我有一个模型类
关键字

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
字段,该字段是
URLField
但对象创建成功


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

先决条件:只有在调用
full\u clean()
时才会进行模型验证。如果您使用ModelForm,则在调用
form.save()
时会为您完成此操作,但如果您上载具有自定义视图逻辑的Excel文件,则需要:

验证模型涉及三个步骤:

  • 验证模型字段-model.clean_fields()
  • 整体验证模型-model.clean()
  • 验证字段唯一性-Model.Validate_unique()
这三个步骤都是在调用模型的full_clean()方法时执行的

正如我前面所说,没有办法告诉URLField需要。为此,您需要覆盖URLValidator

它有一个非常讨厌的正则表达式,您可能不想弄乱它,因此另一种方法是添加额外的验证器:

来自django.core.exceptions的
导入验证错误
从django.utils.deconstruct导入解构
@解构的
类别RequireHttpOrHttpsUrl:
定义调用(自身,值):
如果不是value.startswith(“http://”)而不是value.startswith(“https://”):
引发ValidationError('请提供http或https资源')
类关键字(models.Model):
关键字=models.CharField(verbose_name=“Topic”,最大长度=50)
link=models.URLField(
verbose_name=“下一个最佳行动”,
最大长度=500,空值=True,
验证器=[RequireHttpOrHttpsUrl()]
)
定义(自我):
返回self.keyword
按照注释中的建议使用urllib.parse()时:

我强烈建议在urllib.parse()做得更好的地方使用URLValidator。URL验证程序拒绝:

  • http://
  • http://bla
  • https://bla
接受:

  • https://localhost

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

先决条件:只有在调用
full\u clean()
时才会进行模型验证。如果您使用ModelForm,则在调用
form.save()
时会为您完成此操作,但如果您上载具有自定义视图逻辑的Excel文件,则需要:

验证模型涉及三个步骤:

  • 验证模型字段-model.clean_fields()
  • 整体验证模型-model.clean()
  • 验证字段唯一性-Model.Validate_unique()
这三个步骤都是在调用模型的full_clean()方法时执行的

正如我前面所说,没有办法告诉URLField需要。为此,您需要覆盖URLValidator

它有一个非常讨厌的正则表达式,您可能不想弄乱它,因此另一种方法是添加额外的验证器:

来自django.core.exceptions的
导入验证错误
从django.utils.deconstruct导入解构
@解构的
类别RequireHttpOrHttpsUrl:
定义调用(自身,值):
如果不是value.startswith(“http://”)而不是value.startswith(“https://”):
引发ValidationError('请提供http或https资源')
类关键字(models.Model):
关键字=models.CharField(verbose_name=“Topic”,最大长度=50)
link=models.URLField(
verbose_name=“下一个最佳行动”,
最大长度=500,空值=True,
验证器=[RequireHttpOrHttpsUrl()]
)
定义(自我):
返回self.keyword
按照注释中的建议使用urllib.parse()时:

我强烈建议在urllib.parse()做得更好的地方使用URLValidator。URL验证程序拒绝:

  • http://
  • http://bla
  • https://bla
接受:

  • https://localhost

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

为什么它不是有效的URL?这将解析为相对于当前文档位置的url“world”。因此,如果文档位置是,那么URL世界就是。没有办法强制普通的Django URL字段需要完全限定的URL。实际上,我是通过从excel文件读取数据来保存对象的。如果我没有获得有效链接,我想引发一个错误。e、 g如果在任何特定行中获取
keyword=“macbook”
link=”https://apple.com“
如果get
keyword=“macbook”
link=“apple”,我将保存该对象”
然后将传递一个错误消息,
apple不是有效的url
,函数将返回。我希望我现在把问题说清楚了,您可以指导我。为什么它不是有效的url?这将解析为相对于当前文档位置的url“world”。因此,如果文档位置是,那么URL世界就是。没有办法强制普通的Django URL字段需要完全限定的URL。实际上,我是通过从excel文件读取数据来保存对象的。如果我没有获得有效链接,我想引发一个错误。e、 g如果在任何特定行中获取
keyword=“macbook”
link=”https://apple.com“
如果get
keyword=“macbook”
link=“apple”,我将保存该对象”
然后将传递一个错误消息,
apple不是有效的url
,函数将返回。我希望我现在把问题说清楚了,您可以在这方面指导我。您也可以使用urllib使其更严格一点(例如Python 3.8)
Python from urllib.parse导入URLPASSE parsed=URLPASSE('https://apple.com/foo')bool(parsed.scheme)和bool(parsed.netloc)#True
这是不需要的,因为默认的URLValidator仍然存在,这做得很好