我有一个名为Domain
的模型,如下所示:
class Domain(models.Model):
"""
Model for storing the company domains
"""
user = models.ForeignKey(
User
)
host = models.CharField(
null=False, verbose_name="Host", max_length=128, unique=True
)
我想使用Django的通用视图对此进行CRUD操作。此模型中有一个字段需要用户输入,但外键字段不需要任何用户输入。如何从我的通用视图生成的表单中排除该字段,但为其分配当前经过身份验证的用户的值。
感谢。
答案 0 :(得分:2)
本周早些时候看看罗素对django-users group类似问题的回答。
引用答案*:
表单和视图解决了不同的问题。
View正在解决“如何处理此请求和问题”的问题 把它转换成一个回应?“。表格正在解决”如何 将此请求中的POST数据转换为模型对象(或者 改为模型对象)?“。
非常粗略地说,视图正在执行以下操作:
- 查看获取请求
- 查看是否为GET或POST
- 如果是POST,View会要求表单将帖子转换为模型更改
- 表单返回成功或失败
- View会对表单的成功或失败做出响应。
- 查看返回回复。
醇>表格的功能是完整的子集 View的功能 - 因此,它完全是一个 可互换的内部组件。
现在,在简单的情况下,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"
我猜你说“修复一个字段的值”,你的意思是设置 保存新内容之前,user,name和content_inlined的值 Campaign实例;要做到这一点,你需要注入一些额外的代码 形式的表单处理逻辑:
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
,所以我在上面改了它。