哪个选项最好,1还是2?
1
class TopicForm(forms.Form):
name = forms.CharField(required=True)
body = RichTextFormField(required=True)
def save(self, request):
t = models.Topic(user=request.user,
site=get_current_site(request),
name=self.cleaned_data['name'],
body=self.cleaned_data['body'])
t.slug = slugify(self.name)
t.body_html = seo.nofollow(seo.noindex(self.body))
t.ip = utils.get_client_ip(request)
t.save()
或2.
class Topic(models.Model):
...
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
self.body_html = seo.nofollow(seo.noindex(self.body))
self.ip = utils.get_client_ip(request)
super(Topic, self).save(*args, **kwargs)
答案 0 :(得分:4)
不同之处在于第一个版本仅在通过表单修改对象时应用,而第二个版本仅在保存模型时应用(尽管这仍然是Django中可以修改数据库行的所有方式的子集) )。即使您目前只通过表单创建对象,我认为它仍然是一个有用的区别。
在我看来,两者的混合物在你的情况下是有意义的。 slug
是您始终希望根据name
设置的内容 - 也就是说,它是模型本身固有的内容。另一方面,client_ip
的想法似乎无情地与通过Web请求创建带有表单的对象的概念联系在一起。
当然,您可以更好地了解此模型的具体细节,但这是我处理问题的一般方法。
答案 1 :(得分:0)
这取决于。如果这应该应用于每个模型,那么它在模型中更好。它将向您保证每个Topic
对象都具有正确的值,即使是从管理界面编辑的值也是如此。
表单应该仅用于检查来自用户的数据,并且该模型适合于自动执行此类任务(在保存对象之前生成数据)。请注意,这不应该引发异常或使数据无效。
答案 2 :(得分:0)
我个人更喜欢第二种选择。模型也应该定义业务逻辑,而表单应该只处理用户I / O.这样,即使以编程方式使用(从其他代码导入和调用),您的应用程序也将保持一致。
答案 3 :(得分:0)
你不应该使用2.它更好地使用像保存前或保存后的信号
来源:https://docs.djangoproject.com/en/dev/topics/signals/
@receiver(pre_save, sender=Topic)
def topic_pre_save_handler(sender, instance, **kwargs):
instance.slug = slugify(self.name)
instance.body_html = seo.nofollow(seo.noindex(self.body))
instance.ip = utils.get_client_ip(request)