I am trying to upload a profile image for my user model on user registration, but the image is not getting saved at the media folder, and the default image is displayed. (When I edit the user's image in django admin, it gets saved). Where am I causing this problem, and how to fix it?
My register function in views.py:
def register(request):
if request.method != 'POST':
form = UserCreationForm()
else:
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('account:login')
context = {'form': form}
return render(request, 'account/register.html', context)
My register.html file:
{% extends 'base.html' %} {% block contents %}
<h1>Register</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %} {{form.as_p}}
<input type="submit" name="Create User" />
</form>
{% endblock %}
My user creation form:
class UserCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(
label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email', 'username', 'date_of_birth', 'profile_image')
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
and my User model:
class UserManager(BaseUserManager):
def create_user(self, email, username, date_of_birth, password, profile_image):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
username = username,
date_of_birth= date_of_birth,
profile_image = profile_image,
)
user.set_password(password)
user.save(using=self._db)
return user
class User(AbstractBaseUser):
email = models.EmailField(
verbose_name='email',
max_length=255,
unique=True,
)
username = models.CharField(max_length=20, unique=True)
date_of_birth = models.DateField()
profile_image = models.ImageField(upload_to='profile_pic', default='/profile_pic/default.jpg')
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'date_of_birth']
CodePudding user response:
Uploaded file data is found in request.FILES
, you need to pass this to your form along with the POST data when handling file uploads
form = UserCreationForm(request.POST, request.FILES)
CodePudding user response:
A view handling this form will receive the file data in request.FILES
, which is a dictionary containing a key for each FileField
(or ImageField
, or other FileField
subclass) in the form. So the data from the above form would be accessible as request.FILES['file']
.
Official Example -
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponseRedirect('/success/url/')
else:
form = UploadFileForm()
return render(request, 'upload.html', {'form': form})
In your case, you can use:
form = UserCreationForm(request.POST, , request.FILES)
if form.is_valid():
form.save()
return redirect('account:login')
Notice that we have to pass request.FILES into the form’s constructor; this is how file data gets bound into a form.