为什么图像无法使用django2表单上传?

时间:2019-08-09 15:19:44

标签: django python-3.x django-staticfiles

我正在尝试使用ModelForm类来创建供小公司招聘的人员的表格。因此,我需要他们的身份证(正面和背面)和他们的生活卡的照片。问题是,当我发送表单时,从计算机中选择照片后,它没有在数据库中注册(甚至没有在路径中注册),并且它们也没有复制到所需的媒体文件夹中。不利的是,如果我是通过管理员执行的,那么它可以正常工作,甚至可以在浏览器中打开图像。但是,它们仍然不会上传到媒体文件夹。

models.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)

forms.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')


views.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 ='/ static /'

STATICFILES_DIRS =(     os.path.join(BASE_DIR,“静态”), )

MEDIA_ROOT ='/ media /'

MEDIA_URL ='/ media /'

感谢您的回答!

1 个答案:

答案 0 :(得分:0)

您拥有媒体表单域的表单是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}
    )

但是,您的视图包含一些严重的反模式,这些反模式现在(部分)被建议的解决方案所削弱:

  1. 您不应不要使用request.POST or None,因为有效的POST请求可以为空,但仍然是POST请求;
  2. 如果POST请求成功,则应进行重定向以实现Post/Redirect/Get pattern [wiki];和
  3. 不要使用locals(),因为它将所有变量(甚至是非预期变量)传递到模板。此外,由于不清楚什么传递给模板,以后您可能会倾向于从视图中删除一些变量以进行优化,并且IDE不会发出警告/错误消息这些变量仍然存在模板中必需的。

如果您想添加一条消息,表示提交成功,我建议您使用Django's messaging framework [Django-doc],不要在上下文中传递变量。此框架旨在发布消息,而不管模板本身如何,并防止多次显示同一消息。