Hi all,
I am having a problem saving a Django form using the
FormWizard while using
Django 1.7 and
Python 3.4. Below is my code:
models.py
...
class Advert(models.Model):
... # Some irelevant code removed for brevity
owner = models.ForeignKey(settings.AUTH_USER_MODEL, db_index=True, blank=False, null=False)
title = models.CharField(_("Title"), max_length=120)
description = models.TextField(_("Description"), default='')
category = models.ForeignKey(AdCategory, db_index=True, related_name='ad_category', verbose_name=_('Category'))
status = models.IntegerField(choices=ADVERT_STATES, default=0)
adtype = models.IntegerField(choices=ADTYPES, default=1)
price = models.DecimalField(_('Price'), max_digits=12, decimal_places=2, blank=True, default=0,
help_text=_('Price'), validators=[MinValueValidator(0)])
...
class AdvertImage(models.Model):
def generate_new_filename(instance, filename):
IMAGE_UPLOAD_DIR = "advert_images"
old_fname, extension = os.path.splitext(filename)
return '%s/%s%s' % (IMAGE_UPLOAD_DIR, uuid.uuid4().hex, extension)
advert = models.ForeignKey(Advert, related_name='images')
image = models.ImageField(upload_to=generate_new_filename, null=True, blank=True)
forms.py
from django.forms.models import inlineformset_factory
from django import forms
from django.forms import ModelForm, RadioSelect, TextInput
from .models import Advert, AdvertImage
class AdvertCategoryForm(ModelForm):
class Meta:
model = Advert
fields = ('category',)
class AdvertDetailsForm(ModelForm):
class Meta:
model = Advert
fields = ('title', 'description', 'location', 'adtype', 'price')
class AdvertImageForm(ModelForm):
class Meta:
model = AdvertImage
fields = ('image',)
AdvertImageFormset = inlineformset_factory(Advert, AdvertImage, fields=('image',), can_delete=False, extra=3, max_num=3)
FORMS = [("ad_category", AdvertCategoryForm),
("ad_details", AdvertDetailsForm),
("ad_images", AdvertImageFormset)]
TEMPLATES = {"ad_category": "adverts/advert_category_step.html",
"ad_details": "adverts/advert_details_step.html",
"ad_images": "adverts/advert_images_step.html"}
views.py
...
class AdvertWizard(LoginRequiredMixin, SessionWizardView):
form_list = FORMS
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT))
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
...
def done(self, form_list, **kwargs):
advert = Advert()
"""for form in form_list:
for field, value in form.cleaned_data.iteritems():
setattr(advert, field, value)"""
form_dict = {}
for form in form_list:
form_dict.update(form.cleaned_data)
advert.owner = self.request.user
advert.save()
redirect(advert)
The problem occurs in the done method while saving the form:
ValueError at /ads/new
dictionary update sequence element #0 has length 3; 2 is required
Request Method: | POST |
---|
Request URL: | http://localhost:8000/ads/new |
---|
Django Version: | 1.7.1 |
---|
Exception Type: | ValueError |
---|
Exception Value: | dictionary update sequence element #0 has length 3; 2 is required |
---|
Exception Location: | /home/frank/Projects/python/django/pet_store/src/petstore/apps/adverts/views.py in done, line 147 |
---|
Python Executable: | /home/frank/.virtualenvs/petstore/bin/python |
---|
Python Version: | 3.4.0
/home/frank/Projects/python/django/pet_store/src/petstore/apps/adverts/views.py in done form_dict.update(form.cleaned_data) ...
|
---|
However, when I replace the following code:
form_dict = {}
for form in form_list:
form_dict.update(form.cleaned_data)
with this one
for form in form_list:
for field, value in form.cleaned_data.iteritems():
setattr(advert, field, value)
I now get the following error:
AttributeError at /ads/new
'dict' object has no attribute 'iteritems'
Request Method: | POST |
---|
Request URL: | http://localhost:8000/ads/new |
---|
Django Version: | 1.7.1 |
---|
Exception Type: | AttributeError |
---|
Exception Value: | 'dict' object has no attribute 'iteritems' |
---|
Exception Location: | /home/frank/Projects/python/django/pet_store/src/petstore/apps/adverts/views.py in done, line 140 |
---|
Python Executable: | /home/frank/.virtualenvs/petstore/bin/python |
---|
Python Version: | 3.4.0 |
---|
Python Path: | ['/home/frank/Projects/python/django/pet_store/src/petstore',
'/home/frank/.virtualenvs/petstore/lib/python3.4',
'/home/frank/.virtualenvs/petstore/lib/python3.4/plat-x86_64-linux-gnu',
'/home/frank/.virtualenvs/petstore/lib/python3.4/lib-dynload',
'/usr/lib/python3.4',
'/usr/lib/python3.4/plat-x86_64-linux-gnu',
'/home/frank/.virtualenvs/petstore/lib/python3.4/site-packages' |
---|
Server time: | Thu, 22 Jan 2015 19:25:22 +0300 |
---|
Probably this has to do with the images that have been added through inlineformset, and the lack of iteritems method in Python 3.4.
How can I fix this to be able to save the object along with the images through Django's FormWizard?
Thanks
P.S.: Apologies for the long post.