我对每个用户个人资料都有以下表格:
class UserUpdateForm(forms.ModelForm):
class Meta:
widgets = {'gender':forms.RadioSelect,}
fields = ("username", "email", "is_student","is_professor", "is_executive",)
model = get_user_model() #My model User
class StudentProfileForm(forms.ModelForm):
class Meta:
model = StudentProfile
fields = ('origin_education_school','current_education_school',
'extra_occupation')
class ProfessorProfileForm(forms.ModelForm):
class Meta:
model = ProfessorProfile
fields = ('occupation',)
class ExecutiveProfileForm(forms.ModelForm):
class Meta:
model = ExecutiveProfile
fields = ('occupation', 'enterprise_name', 'culturals_arthistic','ecological')
我有一个URL,可以调用我的AccountProfilesView
基于类的视图,该视图根据用户配置文件创建以前表单的实例:
url(r"^profile/(?P<slug>[\w\-]+)/$", views.AccountProfilesView.as_view(), name='profile'),
我的AccountProfilesView
就是这样:
我这一刻,从AccountProfilesView
基于类的视图我创建了这些形式中的每一个的不同实例,根据
用户个人资料,然后,如果用户拥有is_student
个人资料,则会生成他们的相关表单,因此,通过这种方式生成is_professor
和is_executive
个人资料
如果用户在一个表单中有三个配置文件(is_student,is_professor,is_executive),则会创建或呈现与每个用户配置文件相关的三个表单的字段。
class AccountProfilesView(LoginRequiredMixin, UpdateView):
# All users can access this view
model = get_user_model()
#success_url = reverse_lazy('dashboard')
template_name = 'accounts/profile_form.html'
fields = '__all__'
def get_context_data(self, **kwargs):
context = super(AccountProfilesView, self).get_context_data(**kwargs)
user = self.request.user
if not self.request.POST:
if user.is_student:
profile = user.get_student_profile()
context['userprofile'] = profile
context['form_student'] = forms.StudentProfileForm()
if user.is_professor:
profile = user.get_professor_profile()
context['userprofile'] = profile
context['form_professor'] = forms.ProfessorProfileForm()
print ("profesor form is", context['form_professor'])
if user.is_executive:
profile = user.get_executive_profile()
context['userprofile'] = profile
context['form_executive'] = forms.ExecutiveProfileForm()
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
context = super(AccountProfilesView, self).post(request, *args, **kwargs)
user = self.request.user
# if self.request.method == 'POST':
if user.is_student:
context['form_student'] = forms.StudentProfileForm(
self.request.POST)
elif user.is_professor:
context['form_professor'] = forms.ProfessorProfileForm(
self.request.POST)
elif user.is_executive:
context['form_executive'] = forms.ExecutiveProfileForm(
self.request.POST)
return context
def form_valid(self, form):
context = self.get_context_data(form=form)
user = self.request.user
user = form.save()
if user.is_student:
student = context['form_student'].save(commit=False)
student.user = user
student.save()
if user.is_professor:
professor = context['form_professor'].save(commit=False)
professor.user = user
professor.save()
if user.is_executive:
executive = context['form_executive'].save(commit=False)
executive.user = user
executive.save()
return super(AccountProfilesView, self).form_valid(form)
def get_success_url(self):
return reverse('dashboard')
在我的模板中,我有以下小逻辑:
<form method="POST">
{% csrf_token %}
{% if userprofile.user.is_student %}
<div align="center"><i>My Student Profile data</i></div>
{% bootstrap_form form_student %}
{% endif %}
{% if userprofile.user.is_professor %}
<div align="center"><i>My Professor Profile data</i></div>
{% bootstrap_form form_professor %}
{% endif %}
{% if userprofile.user.is_executive %}
<div align="center"><i>My Executive Profile data</i></div>
{% bootstrap_form form_executive %}
{% endif %}
<input type="submit" value="Save Changes" class="btn btn-default">
</form>
从根据userprofile显示带有字段的表单的角度来看,这种方法有效,表示或呈现与用户配置文件相关的数据或字段
例如,此用户拥有三个配置文件,并在应用程序的配置文件屏幕中显示三种形式:
但是,在执行此类视图屏幕表单的更新时,(其中每个配置文件在其管理自己的数据的地方都有各自的模型/表)发生以下情况:
单击“保存更改”时出现错误:
File "/home/bgarcial/workspace/ihost_project/accounts/views.py", line 185, in post
self.request.POST)
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/http/response.py", line 142, in __setitem__
value = self._convert_to_charset(value, 'latin-1', mime_encode=True)
File "/home/bgarcial/.virtualenvs/ihost/lib/python3.5/site-packages/django/http/response.py", line 115, in _convert_to_charset
raise BadHeaderError("Header values can't contain newlines (got %r)" % value)
django.http.response.BadHeaderError: Header values can't contain newlines (got '<tr><th><label for="id_origin_education_school">Origin education institute:</label></th><td><input id="id_origin_education_school" maxlength="128" name="origin_education_school" type="text" value="Universidad de la Amazonía" required /></td></tr>\n<tr><th><label for="id_current_education_school">Current education institute:</label></th><td><input id="id_current_education_school" maxlength="128" name="current_education_school" type="text" value="Universida EAFIT" required /></td></tr>\n<tr><th><label for="id_extra_occupation">Extra occupation:</label></th><td><input id="id_extra_occupation" maxlength="128" name="extra_occupation" type="text" value="Mother" required /></td></tr>')
[08/Apr/2017 20:21:13] "POST /accounts/profile/luisa/ HTTP/1.1" 500 108206
更确切地说:
我是这么认为的,就是在创建Django表单的表单实例的那一刻,我表示要包含在请求和POST操作中的数据,这是没有经过某种方式验证的
我不知道回溯错误:
BadHeaderError
Header values can't contain newlines (got '<tr><th>) .....
对于让用户发生相同行为的任何用户个人资料,与POST操作中发送的字段相关,属于StudentProfileForm
,ProfessorProfileForm
或ExecutiveProfileForm
< / p>
错误可能出现在我的forms.py中的ModelForms中的字段定义中吗?
<小时/> 的更新
根据@Daniel Roseman回答,我没有覆盖post()
方法,我的AccountProfilesView如下:
class AccountProfilesView(LoginRequiredMixin, UpdateView):
# All users can access this view
model = get_user_model()
#success_url = reverse_lazy('dashboard')
template_name = 'accounts/profile_form.html'
fields = '__all__'
def get_context_data(self, **kwargs):
context = super(AccountProfilesView, self).get_context_data(**kwargs)
user = self.request.user
if not self.request.POST:
if user.is_student:
profile = user.get_student_profile()
context['userprofile'] = profile
context['form_student'] = forms.StudentProfileForm()
if user.is_professor:
profile = user.get_professor_profile()
context['userprofile'] = profile
context['form_professor'] = forms.ProfessorProfileForm()
print ("profesor form is", context['form_professor'])
if user.is_executive:
profile = user.get_executive_profile()
context['userprofile'] = profile
context['form_executive'] = forms.ExecutiveProfileForm()
else:
if user.is_student:
context['form_student'] = forms.StudentProfileForm(
self.request.POST)
if user.is_professor:
context['form_professor'] = forms.ProfessorProfileForm(
self.request.POST)
if user.is_executive:
context['form_executive'] = forms.ExecutiveProfileForm(
self.request.POST)
return context
def form_valid(self, form):
context = self.get_context_data(form=form)
user = self.request.user
user = form.save()
if user.is_student:
student = context['form_student'].save(commit=False)
student.user = user
student.save()
if user.is_professor:
professor = context['form_professor'].save(commit=False)
professor.user = user
professor.save()
if user.is_executive:
executive = context['form_executive'].save(commit=False)
executive.user = user
executive.save()
return super(AccountProfilesView, self).form_valid(form)
def get_success_url(self):
return reverse('dashboard')
前面描述的问题表格中的错误字段消失了。大。但是我此刻的表格并没有将表格的数据保存到数据库中。
我的form_valid
方法中有一些不好的方法吗?
答案 0 :(得分:1)
问题与表单没有任何关系。在post
方法中,您从super
调用中获取响应对象,然后尝试在其上设置值,就好像它是一个dict一样。你做不到;该代码属于get_context_data
。不管怎么说,你不应该压倒一切。