Jon
Jon

Reputation: 12954

Django: ModelForms: ImageField is always empty and rejected by ModelForm

I created a form based on several ModelForm elements. All fields work fine excluding the ImageField. Due to the missing ImageField form.is_valid() always returns False - even though I pass request.FILES to form.

Why the form with the ImageField is always invalid / empty?

Forms

class UserProfileForm2(forms.ModelForm):

    class Meta:
        model = models.UserProfile
        fields = ['description', 'picture']

class LocationForm(forms.ModelForm):
    class Meta:
        model = models.Location
        fields = ['city', 'state', 'country']

class UserForm(forms.ModelForm):
    class Meta:
        model = registration_models.User
        fields = ['first_name', 'last_name']

Models

class Location(models.Model):

    city = models.CharField(max_length=100)
    state = models.CharField(max_length=100)
    country = models.CharField(max_length=100)

    def __unicode__(self):
        return ' - '.join([self.city, self.state, self.country])


class UserProfile(models.Model):

    authenticationuser = fields.AutoOneToOneField(AuthUser)
    description = models.TextField()
    picture = models.ImageField(upload_to='uploaded_files/', null=True)
    location = models.ForeignKey(Location, null=True)
    appear_in_public_ranking = models.BooleanField(default=True)

    def __unicode__(self):
        return self.authenticationuser.username

View

@login_required
def changeprofile(request):
    form = None

    # user posted his new profile settings
    if request.method == 'POST':
        user_form = myforms.UserForm(request.POST)
        user_profile_form = myforms.UserProfileForm2(request.POST, request.FILES)
        location_form = myforms.LocationForm(request.POST)

        forms_are_invalid = not (user_form.is_valid() and user_profile_form.is_valid() and not location_form.is_valid())

        if forms_are_invalid:
            forms = {'user_form':user_form,
                 'user_profile_form':user_profile_form,
                 'location_form':location_form}
            return shortcuts.render(request, 'changeprofile.html', forms)

        location_form.save()
        user_form.save()
        user_profile_form.save()

        return HttpResponseRedirect('/profile')

    else:
        forms = {'user_form':user_form,
            'user_profile_form':user_profile_form,
             'location_form':location_form}
        return shortcuts.render(request, 'changeprofile.html', forms)

Template

        <form action="{% url 'changeprofile' %}" method="post">
        {% csrf_token %}
            {{ user_form }}
            {{ location_form }}
            {{ user_profile_form }}
            <input type="submit" value="Submit" />
        </form>

Upvotes: 1

Views: 1328

Answers (1)

Aamir Rind
Aamir Rind

Reputation: 39709

If your form contains file input then you must set enctype in your form as:

<form action="{% url 'changeprofile' %}" method="post" enctype="multipart/form-data">

Otherwise request.FILES will always be empty.

Upvotes: 7

Related Questions