我有一个URLField,在我的模型中是可选的。我还在ModelForm中将它作为可选项。问题是我只想让表单生成绝对URL。我原以为URLField会自动这样做,但目前它对我不起作用。
因此,为了克服这个问题,我决定覆盖模型上的save()方法。我想覆盖modelform字段上的clean_field()方法;但是,似乎您无法在表单字段上设置“required = False”的clean_field方法。
def save(self,*args, **kwargs):
if self.url:
if not self.url.startswith('http://'):
self.url='http://' + self.url
super(Post, self).save(*args, **kwargs)
我在这里遗漏了什么吗?这完全可以接受吗?
答案 0 :(得分:1)
如果你的模型有一个名为url
的字段并且你在ModelForm上定义了一个clean_url()方法,那么当url存在时它应该被调用,无论它是否是一个可选字段。通过在save方法中执行验证,您可以混合关注点并破坏ModelForm类的设计。在成功调用is_valid()后,应始终认为验证已完成。
但除此之外,你还有另一个问题。
请记住,URL写为scheme://host:port/absolute_path
。绝对路径被编码到URL中,但URL本身不仅仅是绝对路径。
相对路径的问题在于确定它们相对于什么。绝对路径以前导'/'开头,它们始终相对于服务器或文件系统根。相对路径相对于当前活动资源。这里的问题是,当前的活动资源是什么?此外,使save()知道(并因此需要)这些信息肯定是一个破碎的架构。
除此之外,上面的代码将在替代方案(https)上中断,它不会将主机插入到URL中,对于不相对于根的路径,我们如何知道它们相对于哪些?
我认为你有正确的策略可以开始。仅允许输入绝对路径和URL,而不是相对路径。让ModelForm用有效的URL替换绝对路径。要执行此操作,请再次查看ModelForm上clean()方法的documentation,如果在执行此操作时遇到问题,请打开一个针对该问题的新问题。