I have a profile page where I would like to allow a user to upload a profile picture. I can edit all of the text but cannot upload an image. It works if i add the image via the Admin, but not via the user's profile page on the website. Note that when created via admin--it is uploading correctly to the directory (profile_image) that i've specified in media folder. I've created some error handling on template page, but the error generated is this: "The 'image' attribute has no file associated with it." Below is my code:
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
first_name = models.CharField(default='',max_length=100 )
last_name = models.CharField(default='',max_length=100)
email = models.CharField(max_length=100, default='')
date_birth = models.DateField(default=datetime.datetime.now())
bio = models.TextField(default='')
image = models.ImageField(upload_to='profile_image', blank=True)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
views.py
@login_required
def edit_profile(request):
profile = get_object_or_404(models.UserProfile)
if request.method == 'POST':
form = forms.EditProfileForm(data=request.POST, instance=profile)
if form.is_valid():
form.save()
return redirect('/accounts/profile')
else:
form = forms.EditProfileForm(instance=profile)
args = {'form':form}
return render(request, 'accounts/edit_profile.html', args)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserChangeForm
from . import models
class UserProfileForm(forms.ModelForm):
class Meta:
model = models.UserProfile
fields = [
'first_name',
'last_name',
'email',
'date_birth',
'bio',
'image',
]
class EditProfileForm(UserProfileForm):
model = models.UserProfile
fields = [
'first_name',
'last_name',
'email',
'date_birth',
'bio',
'image',
]
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'accounts/media')
edit_profile.html
{% extends "layout.html" %}
{% block title %}User Profile | {{ user }}{{ super }}{% endblock %}
{% block body %}
<h1>My Profile</h1>
<form action="" method="POST" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p}}
<button type="submit">Save</button>
</form>
{% endblock %}
The file comes in request.FILES
, not request.POST
. Do the following in the view:
form = forms.EditProfileForm(data=request.POST, files=request.FILES, instance=profile)
See the documentation on file uploads:
A view handling this form will receive the file data in
request.FILES
, which is a dictionary containing a key for eachFileField
(orImageField
, or otherFileField subclass
) in the form.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With