django - 为什么图片不能用 django2 表单上传?
问题描述
我正在尝试使用 ModelForm 类制作一个表格,供一家小公司招聘的人员使用。所以我需要他们的身份证(正面和背面)和他们的生活卡的照片。问题是当我发送表格时,从我的计算机中选择照片后,它没有在数据库中注册(甚至没有路径),并且它们没有复制到所需的媒体文件夹。不利的是,如果我从管理员那里进行操作,它可以工作,我什至可以在浏览器中打开图像。但是,它们仍然没有上传到媒体文件夹。
模型.py:
from django.db import models
from django.contrib.auth.models import User
class UserExtention (models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, null=True, verbose_name='utilisateur')
phone_number = models.CharField (max_length = 10, null = True, blank=True, verbose_name='numéro de téléphone')
postal_code = models.IntegerField (null = True, blank=True, verbose_name='code postal')
town = models.CharField (max_length=50, null=True, blank=True, verbose_name='ville')
address = models.CharField (max_length=500, null=True, blank=True, verbose_name='adresse')
id_card_recto = models.ImageField (upload_to = 'pictures/id_card_recto', null=True, blank=True, verbose_name="photo du recto de la carte d'identité")
id_card_verso = models.ImageField (upload_to = 'pictures/id_card_verso', null=True, blank=True, verbose_name="photo du verso de la carte d'identité")
vital_card = models.ImageField (upload_to = 'pictures/vital_card', null=True, blank=True, verbose_name="photo de la carte vitale")
hours_number = models.IntegerField (null=True, blank=True, verbose_name="nombre d'heure effectuée par le salarié")
def __str__(self):
return "Profil de {}".format(self.user.username)
表格.py:
from django import forms
from .models import UserExtention
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = (
'password',
'username',
'first_name',
'last_name',
'email',
)
class UserExtentionForm(forms.ModelForm):
class Meta:
model = UserExtention
exclude = ('user', 'hours_number')
视图.py:
from django.shortcuts import render
from .forms import UserForm, UserExtentionForm
def registration (request):
form = UserForm(request.POST or None, request.FILES)
form2 = UserExtentionForm(request.POST or None)
envoi = False
if form.is_valid() and form2.is_valid():
user = form.save()
user_extention = form2.save(commit = False)
user_extention.user = user
user_extention.save()
envoi = True
return render (request, 'registration/registration.html', locals())
模板:
<h1>Ceci est la page principale de l'application nommée "Registration"</h1>
{% if not envoi %}
<form action="{% url "registration" %}" enctype="multipart/form-data" method="post">
{% csrf_token %}
{{ form.as_p}}
{{ form2.as_p}}
<input type="submit" value="submit">
</form>
{% else %}
<p>Votre inscription a bien été prise en compte, vous pouvez à présent vous connecter dans l'onglet <a href="#">connexion</a></p>
{% endif %}
STATIC_URL = '/静态/'
STATICFILES_DIRS = ( os.path.join(BASE_DIR, "static"), )
MEDIA_ROOT = '/媒体/'
MEDIA_URL = '/媒体/'
感谢您的回答!
解决方案
您拥有媒体表单字段的表单是UserExtentionForm
,但在您的代码中,您request.FILES
只传递给UserForm
没有此类媒体字段的 。
def registration (request):
if request.method == 'POST':
form = UserForm(request.POST, request.FILES)
form2 = UserExtentionForm(request.POST, request.FILES)
if form.is_valid() and form2.is_valid():
user = form.save()
user_extention = form2.save(commit = False)
user_extention.user = user
user_extention.save()
return redirect('some-view-name')
else:
form = UserForm()
form2 = UserExtentionForm()
return render (
request,
'registration/registration.html',
{'form': form, 'form2': form2}
)
然而,您的观点包含一些严重的反模式,现在(部分)被提议的解决方案所缓解:
- 你不应该使用,
request.POST or None
因为一个有效的 POST 请求可以是空的,但它仍然是一个 POST 请求; - 如果 POST 请求成功,您应该进行重定向,以实现Post/Redirect/Get模式 [wiki];和
- 请不要使用,
locals()
因为它会将所有变量传递给模板,即使是未定义的变量。此外,由于不清楚您传递给模板的内容,稍后您可能会想从视图中删除一些变量以进行优化,并且 IDE 不会发出警告/错误,这些变量在模板中仍然是必需的。
如果要添加提交成功的消息,我建议你使用Django 的消息传递框架[Django-doc],而不是通过上下文传递变量。该框架旨在发布消息,无论模板本身如何,并防止多次显示相同的消息。
推荐阅读
- orange - 如何在 Orange 中使用 Python Script Widget 进行连接
- javascript - React Native 动态创建的组件在第一次点击时不呈现
- python-3.x - ModuleNotFoundError:没有名为“pygame”的模块
- date - gmdate 和时区 + woo 商务 API
- machine-learning - 特征金字塔网络感受野
- python-3.x - 用俄语文本和 tabula-py 解析 PDF 返回 ???? 结果。(在窗户上)
- javascript - 管道放置下划线底部字母角度
- javascript - $_GET 打破模态框
- java - Java 无法读取从 Windows CA 存储中导出的证书
- ruby-on-rails - 在我看来,尝试使用 get_vote.size 获得投票总数并获得 get_vote 的未定义方法