这是使用django进行图像上传的错误逻辑吗? form.is_valid = false

时间:2015-11-06 13:40:35

标签: django django-models django-forms django-file-upload

我是django的新手,我不确定我是否完全理解表单是如何工作的或如何使用它们。我一直在浏览一些关于文件上传的教程,但看起来有很多不同的方式。我将从上到下包括整个过程。

我收到500错误,因为form.is_valid没有返回true。

我非常感谢任何帮助/提示:)

profile.html

<form role="form" enctype="multipart/form-data" ng-submit="profile.upload_picture()">
    <input id="id_image" type="file" class="" name="image" ng-model="profile.image">
    <input type="hidden" value="{{ profile.user.email }}" ng-model="profile.email">
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

ProfileController.js

function upload_picture() {
    ProfileHandler.setProfilePicture(vm.image, vm.email);
}

ProfileHandler.js

function setProfilePicture(profile_pic, email) {
    return $http.post('/api/v1/profile/picture/', {
        profile_pic: profile_pic,
            email: email
        }).then(imageSuccessFn, imageErrorFn);
    }

ProfilePictureView

class ProfilePictureView(views.APIView):
    def post(self, request):
        if request.method == 'POST':
            form = ProfileImageForm(request.POST, request.FILES)
            if form.is_valid():
                str_data = request.body.decode('utf-8')
                data = json.loads(str_data)
                email = data.get('email', None)
                acc = Account.objects.get(email=email)
                acc.model_pic = form.cleaned_data['image']
                acc.save()
                return Response({
                    'status': 'Accepted',
                    'message': 'Image uploaded.'
                }, status=status.HTTP_202_ACCEPTED)
            else:
                return Response({
                    'status': 'Internal server error',
                    'message': 'Form not valid'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            return Response({
                'status': 'Method not allowed',
                'message': 'Only post is accepted'
            }, status=status.HTTP_405_METHOD_NOT_ALLOWED)

ProfileImageForm

class ProfileImageForm(forms.Form):
    image = forms.FileField(label='Select a profile Image')

AccountModel

class Account(AbstractBaseUser):
    ....
    image = models.ImageField(upload_to='profile_images', blank=True)
    ....

网址(排除某些网址)

urlpatterns = patterns(
    '',
    url(r'^api/v1/', include(router.urls)),
    .....,
    url(r'^api/v1/profile/picture/$', ProfilePictureView.as_view(), name='profile'),
    url('^.*$', IndexView.as_view(), name='index'),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_URL);

Settings.py

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

2 个答案:

答案 0 :(得分:0)

您的表单中没有csrf令牌输入(documentation)。另外,在表单中添加method="post"属性。

<form role="form" method="post" enctype="multipart/form-data" ng-submit="profile.upload_picture()">
    {% csrf_token %}
    <input id="id_image" type="file" class="" name="image" ng-model="profile.image">
    <input type="hidden" value="{{ profile.user.email }}" ng-model="profile.email">
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

答案 1 :(得分:0)

您需要在 profile.htm 文件中的表单中添加{%csrf_token%}。

<form>
    {% csrf_token %}
</form>

这一行的作用是在表单中添加一个包含令牌的隐藏输入字段。令牌与表单一起提交,Django会自动检查令牌的值,以查看此帖子请求是否实际来自您的“前端”而不是其他人的。

另外,添加method="post"

<form method="post">
</form>