Python - Django - Form choicefield and cleaned_data

帅比萌擦擦* 提交于 2019-12-11 23:24:17

问题


I'm having an issue with how cleaned_data seems to work. I want to store the cleaned_data in a session so I can repopulate the form object later. The problem is my choice fields seems to store the display name of the dropdown not the actual value. For example:

<select name="dropdown_element">
<option value="1">Red</option>
<option value="2">Blue</option>
</select>

If I selected Red and used form.cleaned_data['dropdown_element'] I will get the display name Red and not the value of 1. Is there a way to get the value instead of the label?

EDIT

VIEW:

 def vehicle_add_fleet(request):
        if request.POST:
            fleet_form = FleetForm(request.POST, prefix='fleet')
            count_form = CountForm(request.POST, prefix='count', label='# of Odometer Readings')
            if fleet_form.is_valid() and count_form.is_valid():
                request.session['add'] = {}
                request.session['add']['fleet'] = fleet_form.cleaned_data
                return HttpResponseRedirect('/vehicle/add/general/%s/' % (count_form.cleaned_data['count']))
        else:
            fleet_form = FleetForm(prefix='fleet')
            count_form = CountForm(prefix='count', label='# of Odometer Readings')
        return render_to_response('add/fleet.html', {'fleet_form': fleet_form, 'count_form': count_form})

FORM:

class FleetForm(forms.models.ModelForm):
    home_location = forms.ModelChoiceField(queryset=Location.objects.filter(home_only=True), required=False, label=_('Home Location'))
    number = forms.IntegerField(max_value=99999, label=_('Fleet Number'))
    ari_number = forms.IntegerField(max_value=999999, required=False, label=_('ARI Number'))
    class Meta:
        model = Fleet
        exclude = ('status')

MODEL:

class Fleet(models.Model):
     #One-to-Many
        status = models.ForeignKey(Status, verbose_name=_('Status'), default=3)
        pwgsc_spec_code = models.ForeignKey(PWGSCSpecCode, verbose_name=_('PWGSC Specification Code'))
        current_location = models.ForeignKey(Location, related_name='fleet_current', blank=True, null=True, verbose_name=_('Current Location'))
        home_location = models.ForeignKey(Location, related_name='fleet_home', blank=True, null=True, verbose_name=_('Home Location'))
        #Fields
        number = models.PositiveIntegerField(verbose_name=_('Fleet Number'))
        pool_identifier = models.CharField(max_length=1, verbose_name=_('Pool Identifier'))
        ari_number = models.PositiveIntegerField(blank=True, null=True, verbose_name=_('ARI Number'))
        credit_card_number = models.CharField(max_length=16, blank=True, verbose_name=_('Credit Card Number'))
        credit_card_expiry_date = models.DateField(blank=True, null=True, verbose_name=_('Credit Card Expiry Date'))
        company_name = models.CharField(max_length=16, blank=True, verbose_name=_('Company Name'))
        in_service_date = models.DateField(blank=True, null=True, verbose_name=_('In Service Date'))
        reason = models.TextField(blank=True, verbose_name=_('Reason'))

        class Meta:
            verbose_name = _('Fleet')
            verbose_name_plural = _('Fleets')

So basically I want to add the fleet form data (cleaned_data) to the session. However, when I get to the page where I want to save the fleet form, I try and populate it:

def vehicle_add(request):
    #save non-partial forms
    form = FleetForm(request.session['add']['fleet'])
    if form.is_valid():
        return HttpResponse('valid')
    else:
        return HttpResponse('invalid')

And I get an error on the form.is_valid() line:

TypeError at /vehicle/add/fleet/ int() argument must be a string or a number

My current theory is that fleet_form.cleaned_data["home_location"] (for example) stores The display value and not the integer in the value field

Other information:

I was using django 1.1 and upgraded to django 1.3. In all the other examples I see people seem to get the dropdown value and not the dropdown display value. Hope this is enough information!

Thanks for any help


回答1:


Assuming your model is:

class SomeModel(models.Model):
    colour = models.IntegerField(choices=[(1, 'Red'), (2, 'Blue'),])

Your form:

class SomeModelForm(forms.ModelForm):
    class Meta:
        model = SomeModel

Displaying the above form in the template and after a GET/POST should give you the integer value of the colour.




回答2:


Looks Like prefixing your form is causing some strange behavior. I'm not that familiar with using prefix so i can't give you any advice on that, but you aren't prefixing in your vehicle_add_view.

edit

I did some testing

without prefix:

>>> from test.forms import TestForm
>>> form = TestForm(data={'test_field':'test_data'})
>>> form.__dict__
{'files': {}, 'is_bound': True, 'error_class': <class 'django.forms.util.ErrorList'>,
'empty_permitted': False, 'fields': {'test_field': <django.forms.fields.CharField 
object at 0x99d05ac>}, 'initial': {}, 'label_suffix': ':', 'prefix': None, 
'_changed_data': None, 'data': {'test_field': 'test_data'}, '_errors': None, 
'auto_id': 'id_%s'}
>>> form.is_valid()
True
>>> form.cleaned_data
{'test_field': u'test_data'}
>>>    

with prefix:

>>> form = TestForm(data={'test_field':'test_data'}, prefix="foo")
>>> form.__dict__
{'files': {}, 'is_bound': True, 'error_class': <class 'django.forms.util.ErrorList'>,
'empty_permitted': False, 'fields': {'test_field': <django.forms.fields.CharField object 
at 0x99d03cc>}, 'initial': {}, 'label_suffix': ':', 'prefix': 'foo', '_changed_data': 
None, 'data': {'test_field': 'test_data'}, '_errors': None, 'auto_id': 'id_%s'}
>>> form.is_valid()
True
>>> form.cleaned_data
{'test_field': u''}
>>> 

notice that the cleaned_data is missing the value even tho it looks like the data is in the form. Hope that gets you off in the right direction as far as troubleshooting the problem.



来源:https://stackoverflow.com/questions/5436178/python-django-form-choicefield-and-cleaned-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!