Django не может загрузить изображение с помощью multipart/form-data
Я пытаюсь загрузить изображение профиля для моей модели пользователя при регистрации пользователя, но изображение не сохраняется в папке media, и отображается изображение по умолчанию. (Когда я редактирую изображение пользователя в django admin, оно сохраняется). Где я создаю эту проблему, и как ее решить?
Моя функция регистрации в файле 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)
Мой файл register.html:
{% 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 %}
Моя форма создания пользователя:
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
и моя модель пользователя:
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']
Данные загруженного файла находятся в request.FILES
, вам нужно передать их в вашу форму вместе с данными POST при обработке загрузки файлов
form = UserCreationForm(request.POST, request.FILES)
Представление, обрабатывающее эту форму, получит данные файла в request.FILES
, который является словарем, содержащим ключ для каждого FileField
(или ImageField
, или другого подкласса FileField
) в форме. Таким образом, данные из приведенной выше формы будут доступны как request.FILES['file']
.
Официальный пример -
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})
В вашем случае вы можете использовать:
form = UserCreationForm(request.POST, , request.FILES)
if form.is_valid():
form.save()
return redirect('account:login')
Обратите внимание, что мы должны передать request.FILES в конструктор формы; так данные файла привязываются к форме.