图像在request.POST中发送,但在form.cleaned_data中清理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图像在request.POST中发送,但在form.cleaned_data中清理相关的知识,希望对你有一定的参考价值。

我有一个配置文件表单,它接受用于显示用户配置文件图片的图像。

我提交表单时没有问题,但是当访问管理面板时,我可以看到该文件尚未保存。

enter image description here

甚至想,它是在request.POST发送:

'photo':['es_usted_inteligente.jpg']>

SIGNUP REQUEST POST:  <QueryDict: 'csrfmiddlewaretoken': ['SXoar0hPxsKCcMgFG1lJ5XoxjCzbEEqa9x5livVw4M0m9ZB25SGKmL3IUogJnxHz'], 'first_name': ['a'], 'last_name': ['gonzales']
, 'username': ['agonzales'], 'dni': ['744484848'], 'phone_number': ['89898989'], 'birthdate_month': ['1'], 'birthdate_day': ['1'], 'birthdate_year': ['1980'], 'email': ['agon
zales@gmail.com'], 'password1': ['caballo123'], 'password2': ['caballo123'], 'shipping_address1': ['Urb. La Merced Mz.G Lot.32'], 'address_reference': ['Tienda Roja'], 'shipp
ing_department': ['San Martín'], 'shipping_province': ['El Dorado'], 'shipping_district': ['Shatoja'], 'photo': ['es_usted_inteligente.jpg']>

profile_form.cleaned_data:

'照片':无

  profile_form.cleaned_data: 'dni': '48494949', 'phone_number': '9898989', 'birthdate': datetime.date(1980, 1, 1), 'shipping_address1': 'Urb. La Merced Mz.G Lot.32', 'address
_reference': 'Tienda Roja', 'shipping_department': 'Lambayeque', 'shipping_province': 'Chiclayo', 'shipping_district': 'Saña', 'photo': None

视图:

@transaction.atomic
def signupView(request):
    peru = Peru.objects.all()
    department_list = set()
    province_list = set()
    district_list = set()
    for p in peru:
        department_list.add(p.departamento)
    department_list = list(department_list)
    # print("Department List: ", department_list)
    if len(department_list):
        province_list = set(Peru.objects.filter(departamento=department_list[0]).values_list("provincia", flat=True))
        # print("Provice List: ", province_list)
        province_list = list(province_list)
        # print("dfsfs", province_list)
    else:
        province_list = set()
    if len(province_list):
        district_list = set(
            Peru.objects.filter(departamento=department_list[0], provincia=province_list[0]).values_list("distrito",
                                                                                                         flat=True))
        # print("district List: ", district_list)
    else:
        district_list = set()

    if request.method == 'POST':


        #####

        peru = Peru.objects.all()
        department_list = set()
        province_list = set()
        district_list = set()
        for p in peru:
            department_list.add(p.departamento)
        department_list = list(department_list)

        if len(department_list):
            province_list = set(
                Peru.objects.filter(departamento__in=department_list).values_list("provincia", flat=True))

            province_list = list(province_list)

        else:
            province_list = set()
        if len(province_list):
            district_list = set(
                Peru.objects.filter(departamento__in=department_list, provincia__in=province_list).values_list(
                    "distrito",
                    flat=True))

        else:
            district_list = set()

        #####

        user_form = SignUpForm(request.POST)
        profile_form = ProfileForm(district_list, province_list, department_list, request.POST)

        if user_form.is_valid() and profile_form.is_valid():
            user = user_form.save()
            username = user_form.cleaned_data.get('username')
            signup_user = User.objects.get(username=username)
            customer_group = Group.objects.get(name='Clientes')
            customer_group.user_set.add(signup_user)
            raw_password = user_form.cleaned_data.get('password1')
            user.refresh_from_db()  # This will load the Profile created by the Signal

            profile_form = ProfileForm(district_list, province_list, department_list, request.POST,
                                       instance=user.profile)  # Reload the profile form with the profile instance
            profile_form.full_clean()  # Manually clean the form this time. It is implicitly called by "is_valid()" method
            profile_form.save()  # Gracefully save the form

            user = authenticate(username=username, password=raw_password)
            login(request, user)

            return redirect('carrito_de_compras:cart_detail')

        else:
            print(user_form.errors)
            print(profile_form.errors)

    else:

        user_form = SignUpForm()

        profile_form = ProfileForm(district_list, province_list, department_list)


    return render(request, 'accounts/signup.html', 
        'user_form': user_form,
        'profile_form': profile_form
    )

models.朋友:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    birthdate = models.DateField(null=True, blank=True)
    dni = models.CharField(max_length=30, blank=True)
    phone_number = models.CharField(max_length=30, blank=True)
    shipping_address1 = models.CharField(max_length=100, blank=False)
    address_reference = models.CharField(max_length=100, blank=False)
    shipping_department = models.CharField(max_length=100, blank=False)
    shipping_province = models.CharField(max_length=100, blank=False)
    shipping_district = models.CharField(max_length=100, blank=False)
    photo = models.ImageField(upload_to='profile_pics', default='profile_pics/default_profile_pic_white.png')


    def __str__(self):
        return str(self.user.first_name) + "'s profile"

forms.朋友

class ProfileForm(ModelForm):
    MONTHS = 
        1:'ene', 2:'feb', 3:'mar', 4:'abr',
        5:'may', 6:'jun', 7:'jul', 8:'ago',
        9:'set', 10:'oct', 11:'nov', 12:'dic'
    

    def __init__(self, district_list, province_list, department_list, *args, **kwargs):
        super(ProfileForm, self).__init__(*args, **kwargs)
        self.fields['shipping_district'] = forms.ChoiceField(label='Distrito', choices=tuple([(name, name) for name in district_list]))
        self.fields['shipping_province'] = forms.ChoiceField(label='Provincia', choices=tuple([(name, name) for name in province_list]))
        self.fields['shipping_department'] = forms.ChoiceField(label='Departamento', choices=tuple([(name, name) for name in department_list]))


    dni = forms.CharField(label='DNI', max_length=100, required=True)
    phone_number = forms.CharField(label='Celular')
    birthdate = forms.DateField(label='Fecha de nacimiento', widget=SelectDateWidget(years=range(1980, 2012), months=MONTHS))
    shipping_address1 = forms.CharField(label='Dirección de envío', max_length=100, required=True)
    address_reference = forms.CharField(label='Referencia', max_length=100, required=False)
    photo = forms.ImageField(label='Foto de perfil', required=False)

    class Meta:
        model = Profile
        fields = ('dni', 'phone_number', 'birthdate', 'shipping_address1',
                  'address_reference', 'shipping_department', 'shipping_province', 'shipping_district', 'photo')

更新1:

将request.FILES添加到:

    user_form = SignUpForm(request.POST, request.FILES)
    profile_form = ProfileForm(district_list, province_list, department_list, request.POST, request.FILES)

我在request.POST找不到属性照片:

SIGNUP REQUEST POST:  <QueryDict: 'csrfmiddlewaretoken': ['8xcGwGg7z86OclANaEYwdB49u5hrCjOy7gFKSgoqmhxS0CmzeBIUgnYUdRyTnzqJ'], 'first_name': ['g'], 'last_name': ['gonzales']
, 'username': ['ggonzales'], 'dni': ['45484545'], 'phone_number': ['968484848'], 'birthdate_month': ['1'], 'birthdate_day': ['1'], 'birthdate_year': ['1980'], 'email': ['ggon
zales@gmail.com'], 'password1': ['caballo123'], 'password2': ['caballo123'], 'shipping_address1': ['Urb. La Merced Mz.G Lot.32'], 'address_reference': ['Tienda Roja'], 'shipp
ing_department': ['Huancavelica'], 'shipping_province': ['Castrovirreyna'], 'shipping_district': ['Castrovirreyna']>

但是现在,profile_form.cleaned_data至少有deault pic而不是None

Profile Cleaned Data:  'dni': '45484545', 'phone_number': '968484848', 'birthdate': datetime.date(1980, 1, 1), 'shipping_address1': 'Urb. La Merced Mz.G Lot.32', 'address_re
ference': 'Tienda Roja', 'shipping_department': 'Huancavelica', 'shipping_province': 'Castrovirreyna', 'shipping_district': 'Castrovirreyna', 'photo': <ImageFieldFile: profil
e_pics/default_profile_pic_white.png>

表单的HTML:

 <form method="POST" enctype="multipart/form-data" action=".">
                        % csrf_token %
                        <table>
                            <tr>
                                <th> user_form.first_name.label_tag </th>
                                <td>
                                     user_form.first_name.errors 
                                     user_form.first_name 
                                </td>
                            </tr>
                            <tr>
                                <th> user_form.last_name.label_tag </th>
                                <td>
                                     user_form.last_name.errors 
                                     user_form.last_name 
                                </td>
                            </tr>
                            <tr>
                                <th> user_form.username.label_tag </th>
                                <td>
                                     user_form.username.errors 
                                     user_form.username 
                                </td>
                            </tr>
                            <tr>
                                <th> profile_form.dni.label_tag </th>
                                <td> profile_form.dni <i data-toggle="modal" data-target="#exampleModal"
                                                             style="margin-left: 5px"
                                                             class="far fa-question-circle"></i></td>
                            </tr>
                            <tr>
                                <th> profile_form.phone_number.label_tag </th>
                                <td> profile_form.phone_number </td>
                            </tr>
                            <tr>
                                <th> profile_form.birthdate.label_tag </th>
                                <td> profile_form.birthdate </td>
                            </tr>
                            <tr>
                                <th> user_form.email.label_tag </th>
                                <td> user_form.email </td>
                            </tr>
                            <tr>
                                <th></th>
                                <td>
                                    <span class="errorlist"> user_form.password2.errors.0 </span>
                                    <span class="errorlist"> user_form.password2.errors.1 </span>
                                </td>
                            </tr>
                            <tr>
                                <th> user_form.password1.label_tag </th>
                                <td>
                                     user_form.password1.errors 
                                     user_form.password1 
                                </td>
                            </tr>
                            <tr>
                                <th> user_form.password2.label_tag </th>
                                <td>
                                     user_form.password2 

                                </td>
                            </tr>

                        </table>

                </div>


                <div class="col-md-6">

                    <table>

                        <tr>
                            <th> profile_form.shipping_address1.label_tag </th>
                            <td>
                                 profile_form.shipping_address1.errors 
                                 profile_form.shipping_address1 
                            </td>
                        </tr>
                        <tr>
                            <th> profile_form.address_reference.label_tag </th>
                            <td>
                                 profile_form.address_reference.errors 
                                 profile_form.address_reference 
                            </td>
                        </tr>
                        <tr>
                            <th> profile_form.shipping_department.label_tag </th>
                            <td>
                                 profile_form.shipping_department.errors 
                                 profile_form.shipping_department 
                            </td>
                        </tr>
                        <tr>
                            <th> profile_form.shipping_province.label_tag </th>
                            <td>
                                 profile_form.shipping_province.errors 
                                 profile_form.shipping_province 
                            </td>
                        </tr>
                        <tr>
                            <th> profile_form.shipping_district.label_tag </th>
                            <td>
                                 profile_form.shipping_district.errors 
                                 profile_form.shipping_district 
                            </td>
                        </tr>
                        <tr>
                            <th> profile_form.photo.label_tag </th>
                            <td>
                                 profile_form.photo.errors 
                                 profile_form.photo 
                            </td>
                        </tr>
                        <tr>
                            <th>
                                <p></p>
                            </th>
                            <td>
                                <button class="btn btn-secondary" type="submit">Registrarse</button>
                            </td>
                        </tr>


                    </table>

                </div>

                </form>
答案

你需要拿起文件,所以你需要user_form = SignUpForm(request.POST, request.FILES)

此外,请确保您在hmtl中的表单声明中有enctype="multipart/form-data"。像<form id="projectForm" method="POST" enctype="multipart/form-data" action="">之类的东西

以上是关于图像在request.POST中发送,但在form.cleaned_data中清理的主要内容,如果未能解决你的问题,请参考以下文章

Django第3章: Form表单

Django,模型表格未在数据库中保存数据

在 Django 视图中调用“request.POST”时,Ajax POST 不发送数据

使用 Alamofire 发送包含图像和 json 的发布请求

request.POST 在 Django 中的多个图像按钮上

Django request.POST 从输入中获取数据