Django ImageField在提交表单时没有更新



问题描述

我有一个描述UserProfile的模型和一个允许用户更新模型的专用表单。除了photo(ImageField(,一切都很好。photo字段的问题是EditProfileForm根本没有改变图像。换句话说,在表单提交之前和之后,我将相同的图像附加到该字段,photo指向相同的图片,并且没有新的图片上传到服务器。值得注意的是,photo字段正在通过管理面板中的表单进行工作。与UserProfileUser相关的其他字段没有问题:它们都可以更新,并且更新保存在数据库中。

环境详细信息

目前,我使用的Django版本为4.0.3,运行DEBUG=True并内置于开发服务器中。

代码

### Models
def get_image_save_path(
instance,
filename:str
) -> str:
save_dir = instance.__class__.__name__
file_name = uuid.uuid4().hex
file_extension = pathlib.Path(filename).suffix
return f"{save_dir}/{file_name}{file_extension}".lower()
def validate_image_size(image):
if not image:
raise ValidationError("No image found")
if image.size > 512*1024:
raise ValidationError("Max size is 512kb")
class UserProfile(models.Model):
user = models.OneToOneField(User,
on_delete=models.CASCADE,
related_name='user_profile',
primary_key=True)
photo = models.ImageField(upload_to=get_image_save_path,
verbose_name="Photo", 
validators=[validate_image_size],
default="userprofile/default_photo.jpg",
null=False,
blank=False)
bio = models.TextField(default='', blank=True)
def __str__(self):
return f"{self.user.username}"
@receiver(post_save, sender=User)
def create_user_profile(
sender:ModelBase,
instance:User,
created:bool,
**kwargs:Dict) -> None:
if created:
UserProfile.objects.create(user=instance)
else:
return
@receiver(post_save, sender=User)
def save_user_profile(
sender: ModelBase,
instance: User,
**kwargs: Dict) -> None:
instance.user_profile.save()
### Forms
class EditUserForm(ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
class EditProfileForm(ModelForm):
photo = ImageField(widget=FileInput(attrs={'class': 'form-control-file'}))
class Meta:
model = UserProfile
fields = ('photo', 'bio')
### Views
@login_required
def profile_view(request):
return render(request, 
template_name="accounts/profile_view.html",
context = {})
@login_required
def profile_edit(request):
if request.method == 'POST':
userForm = EditUserForm(data=request.POST, instance=request.user)
profileForm = EditProfileForm(data=request.POST, 
files=request.FILES, 
instance=request.user.user_profile)
if userForm.is_valid() and profileForm.is_valid():
profileForm.save()
userForm.save()
return redirect('accounts_app:profile_view')
else:
userForm = EditUserForm(instance=request.user)
profileForm = EditProfileForm(instance=request.user.user_profile)
context = {"userForm": userForm, "profileForm": profileForm, }
return render(request, 'accounts/edit_profile.html', context)
### Template
{% block content %}
<div class="row">
<div class="panel panel-primary panel-login rounded-lg">
<div class="panel-body">
<form class="" action="" method="POST">
{% csrf_token %}
{% for field in userForm %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
{% for field in profileForm %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button class="btn btn-danger standard-btn" type="submit">Zapisz zmiany</button>
</form>
</div>
</div>
</div>
{% endblock %}

问题

我在代码中做错了什么,导致并描述了photo字段的问题?

尝试这个

当您的表单包含任何元素时,请使用多部分/表单数据

在模板中

<form class="" action="" method="POST" enctype="multipart/form-data">

最新更新