2

I'm trying to upgrade existing application from version 1.4 to 1.11. I have an issue where MultipleChoiceField is getting stored in database but template does not render those as being checked.

models.py

class TestModel(models.Model):
    test = models.CharField(blank=True, max_length=200)

forms.py

from django import forms
from django.forms import ModelForm
from app.models import TestModel
CHOICES = (
    ('1', 'Select All'),
    ('a', 'choice 1'),
    ('k', 'choice 2'),
)
class TestForm(ModelForm):
    test = forms.MultipleChoiceField(choices=CHOICES, required=False, widget=forms.CheckboxSelectMultiple()
    )
    class Meta:
        model = TestModel
        fields = '__all__' 

form1 = TestForm(data={'test': ['a','k']})

When I run this using the manage.py shell I get the correct HTML output

print form1

<tr>
<th><label>Test:</label></th>
<td>
<ul id="id_test">
    <li>
    <label for="id_test_0"><input type="checkbox" name="test" value="1" id="id_test_0" onclick="selectAll(this);" />Select All</label>
    </li>
    <li>
    <label for="id_test_1"><input type="checkbox" name="test" value="a" checked id="id_test_1" onclick="selectAll(this);" />choice 1</label>
    </li>
    <li>
    <label for="id_test_2"><input type="checkbox" name="test" value="k" checked id="id_test_2" onclick="selectAll(this);" />choice 2</label>
    </li>
</ul>
</td>
</tr>   

You can see that it has the checked attribute in the code.

Template

<div id="Scrolldrive2">{{form1.test}}</div> 

The selected checkboxes are not rendered on the UI.

bijalscm
  • 445
  • 3
  • 5
  • 14

1 Answers1

1

Issue was due to initial data returned from model was of type string

eg. form1 = TestForm(initial={'test': u"[u'a', u'k']"})

Django 1.4 could convert data to list internally which was not happening with 1.11.Have converted initial data to list and now it is working fine.

Working snippet which renders a 'test' field data as list type instead of string type in forms.py

import json
def jsonify(data):
    return json.loads(data.replace("u'", "'").replace("'", '"'))
    #output is [u'a', u'k']  


class TestForm(ModelForm):
    test = forms.MultipleChoiceField(choices=CHOICES, required=False, 
           widget=forms.CheckboxSelectMultiple())
    class Meta:
        model = TestModel
        fields = '__all__' 
    def __init__(self, *args, **kwargs):
        super(TestForm, self).__init__(*args, **kwargs)
        if self.instance:
            obj_data = self.instance.__dict__ 
            self.initial['test'] = jsonify(obj_data['test'])  
bijalscm
  • 445
  • 3
  • 5
  • 14
  • I'm upgrading django 1.8 to 1.11 and this same thing was making me crazy. This saved me refactoring my data and/or making a much worse hack. Having it in the form was just the right level! Thanks! – bethlakshmi Oct 07 '19 at 04:33