Tuesday, January 27, 2015

Re: Unable to save object with images while using FormWizard in Django 1.7 and Python 3.4

Hi,

Use items() instead of iteritems().

Collin

On Thursday, January 22, 2015 at 11:31:23 AM UTC-5, Frankline wrote:
​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
    1.             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.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/6cfff14b-17b7-44b6-bb2a-74bdf7b467df%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment