从一个视图将数据绑定到一个或多个表单 - BadHeaderError at - 标题值不能包含换行符()

时间:2017-04-08 22:06:21

标签: python django-forms django-views

我对每个用户个人资料都有以下表格:

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_professoris_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显示带有字段的表单的角度来看,这种方法有效,表示或呈现与用户配置文件相关的数据或字段

例如,此用户拥有三个配置文件,并在应用程序的配置文件屏幕中显示三种形式:

enter image description here

但是,在执行此类视图屏幕表单的更新时,(其中每个配置文件在其管理自己的数据的地方都有各自的模型/表)发生以下情况:

单击“保存更改”时出现错误:

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

更确切地说:

enter image description here

我是这么认为的,就是在创建Django表单的表单实例的那一刻,我表示要包含在请求和POST操作中的数据,这是没有经过某种方式验证的

我不知道回溯错误:

BadHeaderError
Header values can't contain newlines (got '<tr><th>) .....

对于让用户发生相同行为的任何用户个人资料,与POST操作中发送的字段相关,属于StudentProfileFormProfessorProfileFormExecutiveProfileForm < / 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方法中有一些不好的方法吗?

1 个答案:

答案 0 :(得分:1)

问题与表单没有任何关系。在post方法中,您从super调用中获取响应对象,然后尝试在其上设置值,就好像它是一个dict一样。你做不到;该代码属于get_context_data。不管怎么说,你不应该压倒一切。