如何序列化多个复选框字段以便正确提交表单?

时间:2016-12-21 00:31:19

标签: python django django-forms

我有一个字体列表,我想通过多个复选框选择提交,我想在另一个页面上显示所有选中的复选框。当我提交表单时,我收到了这个错误:

[<Font: Space Mono>, <Font: Fruktur>] is not JSON serializable

如何在没有此问题的情况下提交表单?

views.py

def step1(request):
    initial={'fn': request.session.get('fn', None), 'checkbox': request.session.get('checkbox', (False,))} #cookies
    form = PersonForm(request.POST or None, initial=initial)
    if request.method == 'POST':

        if form.is_valid():
            request.session['fn'] = form.cleaned_data['fn']
            request.session['checkbox'] = form.cleaned_data['checkbox'] #probably this line is wrong, how can I serialize it ?
            return HttpResponseRedirect(reverse('step2'))
    return render(request, 'step1.html', {'form': form})

forms.py

class CustomChoiceField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return mark_safe('%s' % (obj.font_name))

class PersonForm(forms.ModelForm):
    checkbox = CustomChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Font.objects.all())

    class Meta:
        model = Person
        fields = ['fn', 'checkbox']

有什么建议吗?

更新:Django Traceback

TypeError at /multistep/step1/

[<Font: Space Mono>, <Font: Fruktur>] is not JSON serializable

Request Method:     POST
Request URL:    http://127.0.0.01:8000/multistep/step1/
Django Version:     1.8.17
Exception Type:     TypeError
Exception Value:    

[<Font: Space Mono>, <Font: Fruktur>] is not JSON serializable

Exception Location:     C:\Python34\lib\json\encoder.py in default, line 173
Python Executable:  C:\Python34\python.exe
Python Version:     3.4.4
Python Path:    

['C:\\Python34\\projects\\fyzai',
 'C:\\Python34\\lib\\site-packages\\django_flickr-0.3.5-py3.4.egg',
 'C:\\Python34\\lib\\site-packages\\oauth2-1.9.0.post1-py3.4.egg',
 'C:\\Python34\\lib\\site-packages\\django_taggit_templatetags-0.4.6.dev0-py3.4.egg',
 'C:\\Python34\\lib\\site-packages\\django_taggit-0.20.2-py3.4.egg',
 'C:\\Python34\\lib\\site-packages\\bunch-1.0.1-py3.4.egg',
 'C:\\Python34\\lib\\site-packages\\django_templatetag_sugar-1.0-py3.4.egg',
 'C:\\Python34\\lib\\site-packages\\aldryn_newsblog-1.3.0-py3.4.egg',
 'C:\\WINDOWS\\SYSTEM32\\python34.zip',
 'C:\\Python34\\DLLs',
 'C:\\Python34\\lib',
 'C:\\Python34',
 'C:\\Python34\\lib\\site-packages']

Server time:    Wed, 21 Dec 2016 00:22:08 +0000
Traceback Switch to copy-and-paste view

    C:\Python34\lib\site-packages\django\core\handlers\base.py in get_response

                                    response = middleware_method(request, response)

         ...
    ▶ Local vars
    C:\Python34\lib\site-packages\django\contrib\sessions\middleware.py in process_response

                                            request.session.save()

         ...
    ▶ Local vars
    C:\Python34\lib\site-packages\django\contrib\sessions\backends\db.py in save

                                session_data=self.encode(self._get_session(no_load=must_create)),

         ...
    ▶ Local vars
    C:\Python34\lib\site-packages\django\contrib\sessions\backends\base.py in encode

                            serialized = self.serializer().dumps(session_dict)

         ...
    ▶ Local vars
    C:\Python34\lib\site-packages\django\core\signing.py in dumps

                            return json.dumps(obj, separators=(',', ':')).encode('latin-1')

         ...
    ▶ Local vars
    C:\Python34\lib\json\__init__.py in dumps

                            **kw).encode(obj)

         ...
    ▶ Local vars
    C:\Python34\lib\json\encoder.py in encode

                            chunks = self.iterencode(o, _one_shot=True)

         ...
    ▶ Local vars
    C:\Python34\lib\json\encoder.py in iterencode

                            return _iterencode(o, 0)

         ...
    ▶ Local vars
    C:\Python34\lib\json\encoder.py in default

                            raise TypeError(repr(o) + " is not JSON serializable")

         ...
    ▶ Local vars

1 个答案:

答案 0 :(得分:0)

完整堆栈跟踪显示会话中间件导致此序列化错误。而这又是由以下几行引起的

request.session['fn'] = form.cleaned_data['fn']
request.session['checkbox'] = form.cleaned_data['checkbox'] #probably this line is wrong, how can I serialize it ?

同样不清楚它是如何产生这个错误的,但是看着你的表单,它表明有一个字体查询集被序列化。为此,您需要设置一个特殊的序列化程序,但将其挂入会话将很困难。相反,为什么不只是:

checkbox = CustomChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Font.objects.all().values())

在这种情况下,您必须将obj.font_name更改为obj ['font_name']