Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 837
Pauli Avatar asked Mar 25 '15 02:03

Pauli


1 Answers

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">
like image 140
catavaran Avatar answered Sep 30 '22 17:09

catavaran