如果使用 form.instance 设置值,Django 表单验证将失败
Django form validation fails if value set using form.instance
我正在尝试使用通用视图将当前登录的用户作为属性分配给模型实例的字段。我已经多次提到 this SO post and did override post
method but it was giving me an error that CreatedBy field was required. Also I have gone through mro
on ccbv。查看如下。
class PostCreate(LoginRequiredMixin, CreateView):
model = Post
form_class = PostForm
success_message = "Post Updated"
success_url = '/home/'
def get_form(self, form_class=None):
"""
Returns an instance of the form to be used in this view.
"""
form = super(PostCreate, self).get_form(form_class)
form.instance.CreatedBy=User.objects.get(id=self.request.user.id)
return form
def get_initial(self):
"""
Returns the initial data to use for forms on this view.
"""
self.initial = {'CreatedBy': User.objects.get(id=self.request.user.id)}
return self.initial.copy()
def get_form_kwargs(self):
"""
Returns the keyword arguments for instantiating the form.
"""
kwargs = {
'initial': self.get_initial(),
'prefix': self.get_prefix(),
}
if self.request.method in ('POST', 'PUT'):
kwargs.update({
'data': self.request.POST,
'files': self.request.FILES,
})
return kwargs
我之所以覆盖所有这些方法是为了检查每个方法中初始字典的可用性。它在每种方法中都可用,但表单验证仍然失败。但我认为最好不要在 get_initial(self)
中设置值,因为我不会使用任何已保存对象的现有数据预填充表单字段,而是我想 update a field of an initialized form with User object of logged in user
。我已经在 ipdb
中完成了控制流程,但最终遇到了同样的错误。
ipdb> form.initial={'CreatedBy':User.objects.get(id=request.user.id)}
ipdb> form.fields['CreatedBy']=User.objects.get(id=request.user.id)
ipdb> form.instance.CreatedBy=User.objects.get(id=request.user.id)
ipdb> form.is_valid()
False
ipdb> form.instance.CreatedBy
<User: userone>
ipdb> form.fields['CreatedBy']
<User: userone>
ipdb> form.initial
{'CreatedBy': <User: userone>}
请注意,我不是在寻找被操纵的 form_valid(self)
方法。
我被这个问题困扰了几个小时。非常感谢任何帮助。
仍然需要 created_by 的原因是您没有将其从表单本身中排除;您需要在 PostForm 中执行此操作。
class PostForm(forms.ModelForm):
class Meta:
exclude = ['created_by']
至于自动分配,编辑视图的文档有一个 specific section 描述了如何做到这一点;你覆盖 form_valid()
:
def form_valid(self, form):
form.instance.created_by = self.request.user
return super(PostCreate, self).form_valid(form)
我正在尝试使用通用视图将当前登录的用户作为属性分配给模型实例的字段。我已经多次提到 this SO post and did override post
method but it was giving me an error that CreatedBy field was required. Also I have gone through mro
on ccbv。查看如下。
class PostCreate(LoginRequiredMixin, CreateView):
model = Post
form_class = PostForm
success_message = "Post Updated"
success_url = '/home/'
def get_form(self, form_class=None):
"""
Returns an instance of the form to be used in this view.
"""
form = super(PostCreate, self).get_form(form_class)
form.instance.CreatedBy=User.objects.get(id=self.request.user.id)
return form
def get_initial(self):
"""
Returns the initial data to use for forms on this view.
"""
self.initial = {'CreatedBy': User.objects.get(id=self.request.user.id)}
return self.initial.copy()
def get_form_kwargs(self):
"""
Returns the keyword arguments for instantiating the form.
"""
kwargs = {
'initial': self.get_initial(),
'prefix': self.get_prefix(),
}
if self.request.method in ('POST', 'PUT'):
kwargs.update({
'data': self.request.POST,
'files': self.request.FILES,
})
return kwargs
我之所以覆盖所有这些方法是为了检查每个方法中初始字典的可用性。它在每种方法中都可用,但表单验证仍然失败。但我认为最好不要在 get_initial(self)
中设置值,因为我不会使用任何已保存对象的现有数据预填充表单字段,而是我想 update a field of an initialized form with User object of logged in user
。我已经在 ipdb
中完成了控制流程,但最终遇到了同样的错误。
ipdb> form.initial={'CreatedBy':User.objects.get(id=request.user.id)}
ipdb> form.fields['CreatedBy']=User.objects.get(id=request.user.id)
ipdb> form.instance.CreatedBy=User.objects.get(id=request.user.id)
ipdb> form.is_valid()
False
ipdb> form.instance.CreatedBy
<User: userone>
ipdb> form.fields['CreatedBy']
<User: userone>
ipdb> form.initial
{'CreatedBy': <User: userone>}
请注意,我不是在寻找被操纵的 form_valid(self)
方法。
我被这个问题困扰了几个小时。非常感谢任何帮助。
仍然需要 created_by 的原因是您没有将其从表单本身中排除;您需要在 PostForm 中执行此操作。
class PostForm(forms.ModelForm):
class Meta:
exclude = ['created_by']
至于自动分配,编辑视图的文档有一个 specific section 描述了如何做到这一点;你覆盖 form_valid()
:
def form_valid(self, form):
form.instance.created_by = self.request.user
return super(PostCreate, self).form_valid(form)