Pauli
Pauli

Reputation: 1265

Django: How can I update the profile pictures via ModelForm?

I'm trying to write a small Django system. After logging into the system, a user can edit and save his/her own profile information. The fields involved are: username, email, first name, last name, website and picture.

The problem: The picture cannot be updated (After selecting an image and clicking "update" button, it shows "No file selected". The profile picture displayed on the page is still the old one). But the other fields are all OK.

Here are my codes:

models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(User)

    website = models.URLField(blank=True)
    picture = models.ImageField(upload_to="profile_images", blank=True)

    def __str__(self):
        return self.user.username

forms.py:

class UserForm2(forms.ModelForm):

    class Meta:
        model = User
        fields = ('username', 'email', 'first_name', 'last_name')

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('website', 'picture')

views.py:

@login_required
def update_user(request):

    try:
        user_profile = UserProfile.objects.get(user=request.user)
    except UserProfile.DoesNotExist:
        return HttpResponse("invalid user_profile!")

    if request.method == "POST":
        update_user_form = UserForm2(data=request.POST, instance=request.user)
        update_profile_form = UserProfileForm(data=request.POST, instance=user_profile)

        if update_user_form.is_valid() and update_profile_form.is_valid():
            user = update_user_form.save()
            profile = update_profile_form.save(commit=False)
            profile.user = user

            if 'picture' in request.FILES:
                profile.picture = request.FILES['picture']

            profile.save()

        else:
            print(update_user_form.errors, update_profile_form.errors)
    else:
        update_user_form = UserForm2(instance=request.user)
        update_profile_form = UserProfileForm(instance=user_profile)

    return render(request,
            'userprofile/update_user.html',
            {'update_user_form': update_user_form, 'update_profile_form': update_profile_form}
            )

update_user.html:

<form id="update_user_form" method="POST" action="/userprofile/update_user/">
    {% csrf_token %}
    {{ update_user_form.as_p }}
    {{ update_profile_form.as_p }}
    <img src="{{ update_profile_form.instance.picture.url }}" />
    <br />
    <input type="SUBMIT" name="submit" value="Update"/>
</form>

How can I make it work properly?

Upvotes: 7

Views: 7333

Answers (1)

catavaran
catavaran

Reputation: 45555

To upload the file you should add the enctype attribute to the <form> tag:

<form id="update_user_form" method="POST" action="/userprofile/update_user/"
                            enctype="multipart/form-data">

Upvotes: 5

Related Questions