Django save()覆盖,最佳实践:在模型,表单或视图上?

时间:2017-08-24 00:08:44

标签: django django-models django-forms django-views

我通过覆盖save()这样的功能成功地对我的自定义用户模型的密码进行了哈希扫描:

def save(self, commit = True): 
    user = super(RegisterForm, self).save(commit = False)
    user.set_password(self.cleaned_data["password1"])
    if commit:
        user.save()
    return user

但是我已经在我的注册表单定义中放置了这个覆盖,我刚刚发现我也可以在用户模型定义或我的register()视图中执行此操作。

是否有正确的"是否可以覆盖这些功能,例如clean()save()?有什么实际区别吗?

ps:我对使用Django的默认密码更改和注册视图或表单不感兴趣。

1 个答案:

答案 0 :(得分:3)

在挖掘源代码后,我发现ModelForm的save()方法要调用Model的(Model Instance)save()方法。检查here.

现在很明显,第一个ModelForm的save()被调用并且在其中(取决于提交值)模型的save()被调用。

同样值得注意的是在代码中:

def save(self, commit = True): 
    user = super(RegisterForm, self).save(commit = False)
    user.set_password(self.cleaned_data["password1"])
    #When you're hashing and setting the password to the user variable,
    #this user variable is a Model Object but is not saved in the database yet. 
    if commit:
        user.save()
        #Now in the above line you're ultimately calling the save method of Model instance.
    return user

所以问题归结于你。

你想在django模型的抽象层(通过重写模型实例的保存方法)上再走一步吗?

你真的需要这样做吗?

抽象是OOPS的构建块之一。因此,在需要出现实际需要您在抽象层中进行上述之前,为什么要这样做呢? 显然,密码可以在ModelForm的save()方法中进行哈希处理。

另外,如果你在抽象中上面一层, 如果将来发生意外行为该怎么办?

在我看来,为什么不将它留在ModelForm中呢?当我们开始使用django时,我们从抽象的最高层开始(我们只是调用方法,通常不知道我们继承的类中发生了什么;这就是oops的用途)我们只在出现了特殊需求。

希望这会以某种方式引导你。感谢。