尝试在Django中上传图像时出现MultiValueDictKeyError

时间:2017-10-19 21:41:42

标签: python html mysql django

您好我尝试使用Django通过表单字段上传图像文件,并在尝试提交表单时获取django.utils.datastructures.MultiValueDictKeyError。

这是我的forms.py:

class UserProfileForm(forms.ModelForm):
    type = forms.ModelChoiceField(queryset=UserType.objects.all(), required=True)
    phone = forms.CharField(required=False)
    address = forms.CharField(required=False)
    picture = forms.ImageField(required=False)
    class Meta:
        model = UserProfile # matches data model
        fields = ('type','phone','address','picture') # shown on the form

这是我的models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    type = models.ForeignKey(UserType, on_delete=models.CASCADE)
    phone = models.CharField(max_length=10, blank=True)
    address = models.CharField(max_length=128, blank=True)
    picture = models.ImageField(upload_to='profile_images', blank=True)
    def __str__(self):
        return self.user.username

这是我的views.py:

def register(request):
    if request.method == 'POST':
        response = {}

        username = request.POST.get('username')
        password1 = request.POST.get('password1')
        password2 = request.POST.get('password2')
        type = request.POST.get('type')
        first_name = request.POST.get('first_name')
        last_name = request.POST.get('last_name')
        email = request.POST.get('email')
        phone = request.POST.get('phone')
        address = request.POST.get('address')
        picture = request.POST.get('picture')

        data = {'username': username,
                'password1': password1,
                'password2': password2,
                'type': UserType.objects.get(type=type).pk,
                'first_name': first_name,
                'last_name': last_name,
                'email': email,
                'phone': phone,
                'address': address,
                'picture': picture}
        user_form = UserForm(data)
        profile_form = UserProfileForm(data)

        if user_form.is_valid() and profile_form.is_valid():
            user = user_form.save()
            user.set_password(data['password1'])
            user.save()
            profile = profile_form.save(commit=False)
            profile.user = user
            #if 'picture' in request.FILES:
                #profile.picture = request.FILES['picture']
            #picture = Image.open(StringIO(profile_form.cleaned_data['picture'].read()))
            #picture.save(MEDIA_DIR, "PNG")
            #newPic = Pic(imgfile=request.FILES['picture'])
            newPic=request.FILES['picture']
            newPic.save()
            profile.save()
            return JsonResponse({'response': 'success'})
        else:
            errors =  user_form.errors.copy()
            errors.update(profile_form.errors)
            return JsonResponse({'response': errors})

这是我的HTML表单:

<form class="uk-form-horizontal uk-margin-small" id="registration_form" 
            method="post" action="{% url 'register' %}" enctype="multipart/form-data">

        <div class="uk-margin">
                <label class="uk-form-label" for="form-horizontal-text">Profile photo</label>
                <div class="uk-form-controls">
                    <div class="uk-width-1-1" uk-form-custom="target: true">
                        <input name="picture" id="id_picture" type="file">
                        <input class="uk-input" type="text" placeholder="Select file" disabled>
                    </div>
                </div>
            </div>

        <div class="uk-margin-top">
                        <button class="uk-button uk-button-primary uk-width-1-1" type="submit" value="Submit" />Register</button>
                    </div>
                </div>
            </div>  

 </form>    

我试图在AJAX函数中传递注册表单的值:

$(document).on('submit','#registration_form',function(e){
    e.preventDefault();

    //if (password_match){
        $.ajax({
            type:'POST',
            url: "{% url 'register' %}",
            data:{
                username: $('#id_reg_username').val(),
                password1: $('#id_password1').val(),
                password2: $('#id_password2').val(),
                type: $('#id_user_type').val(),
                first_name: $('#id_first_name').val(),
                last_name: $('#id_last_name').val(),
                email: $('#id_email').val(),
                phone: $('#id_phone').val(),
                address: $('#id_address').val(),
                //PICTURE UPLOAD HERE?
                picture: $('#id_picture').val(),
                csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()  

我在这里尝试使用Google搜索和其他解决方案,我无法接受并保存图片,有人可以帮忙吗?

4 个答案:

答案 0 :(得分:0)

不要将POST用于文件

改为使用FILES。例如:photo = request.FILES['photo']

答案 1 :(得分:0)

当您提供输入文件字段并且用户提交表单而不上传任何照片时,也会发生这种情况。特别是如果您没有设置输入文件的必需属性。

您需要在视图中编写一个函数来测试照片是否已上传!

答案 2 :(得分:0)

您可以使用 request.dataget() 方法来像这样提取传入的值

    def create(self, request, *args, **kwargs):
    course_owner = User.objects.get(email=request.auth.get('user_id'))
    image = request.data.get('image')
    video = request.data.get('video')
    image_upload = cloudinary.uploader.upload(image)
    video_upload = cloudinary.uploader.upload(video)
    request.data['course_owner'] = course_owner.id
    request.data['image'] = image_upload.get('url')
    request.data['video'] = video_upload.get('url')
    serialized = CourseModelSerializer(data=request.data)

答案 3 :(得分:0)

表单元素中的属性应该是enctype,而不是encrypt。

<form method="post" enctype="multipart/form-data"></form>