请查看 Russel 本周早些时候在 django-users group 上对类似问题的回答。
引用答案*:
表单和视图解决不同的问题。
View 正在解决“我如何处理这个请求和
将其转换为响应?”。表单正在解决“如何
我是否将此请求中的 POST 数据转换为模型对象(或
更改为模型对象)?”。
非常粗略地说,一个视图正在执行以下操作:
- View 收到请求
- 查看判断这是 GET 还是 POST
- 如果是 POST,View 会要求表单将 Post 转换为模型更改
- 表单返回成功或失败
- View 响应 Form 的成功或失败。
- 视图返回响应。
表单的功能是
视图的功能——因此,它完全是一个
可互换的内部组件。
现在,在简单的情况下,View 可以猜测所有
表单的默认值——它只需要知道你正在处理
使用 Foo 模型,它可以构造一个默认的 Foo ModelForm。
但是,如果您有更复杂的表单要求,则
需要一个自定义的表单。
我们可以通过公开所有选项来实现这一点
View 类上的 ModelForm;但为了保持一切清洁,我们
保持 ModelForm 隔离,并为 View 提供了一种方法
指定它将使用哪个 Form 类。
所以 - 为了涵盖排除字段的用例,您定义了一个
排除字段的 ModelForm,然后让 CreateView 知道
您要使用的表格:
class CampaignForm(forms.ModelForm):
class Meta:
model = Campaign
exclude = ('user', 'name', 'content_inlined')
class CreateCampaignView(CreateView):
form_class = CampaignForm
template_name = "forms/create.html"
我猜当您说“修复字段的值”时,您的意思是设置
保存新文件之前的用户、名称和内容内联值
活动实例;为此,您需要注入一些额外的代码
表单的表单处理逻辑:
class CreateCampaignView(CreateView):
form_class = CampaignForm
template_name = "forms/create.html"
def form_valid(self, form):
form.instance.user = ... (something meaningful.. e.g., self.request.user)
return super(CreateCampaignView, self).form_valid(form)
这会覆盖表单有效时的默认行为,并设置
额外的价值。然后 form_valid() 的 super() 实现将
保存实例。
为了记录,这也可以通过覆盖 save()
ModelForm 上的方法——但是,如果你这样做,你会失去
请求对象,如果您尝试设置
实例值到对请求敏感的东西。
*原始答案集self.object.user 而不是form.instance.user。这给出了一个AttributeError,所以我在上面进行了更改。