使用Angular的Django Rest框架文件上传

时间:2014-12-03 12:51:20

标签: django angularjs curl file-upload

几个小时我一直试图让FileUpload使用DRF和Angular。我有这样的观点:

class FileUploadView(APIView):
    parser_classes = (MultiPartParser,)

    def post(self, request, pk):
         print request.FILES
         #do something
         return Response(status=204)

我正在使用像这样的angular-file-upload(https://github.com/nervgh/angular-file-upload/wiki/Module-API)(getCookie()函数来自here):

var csrf = getCookie('csrftoken'); 

    $scope.uploader = new FileUploader({
        queueLimit:1,
        url:'upload',
        method: 'POST',
        headers : {
        'X-CSRF-TOKEN': csrf
        }
    });

但是,当我使用curl将数据发送到url时,它可以工作:

curl -X POST \
    --dump-header - \
    -H "Content-Type:multipart/form-data" \
    -u admin:admin \
    -F "image=@/Users/magda/test.pdf;type=application/pdf" \
http://localhost:8000/lectures/166/upload

但每当我使用角度函数时,我得到:

detail: "CSRF Failed: CSRF token missing or incorrect."

我还尝试将csrf_exempt添加到该函数中,该函数没有任何改变。我做错了什么?

2 个答案:

答案 0 :(得分:0)

我收到与使用angular-file-upload时相同的错误。我只是抓取了csrf令牌并将其包含在我的数据中,所以django会允许它。

$scope.$watch('files', function() {
      if($scope.files) {
          var csrf = $cookies.csrftoken;
          for (var i = 0; i < $scope.files.length; i++) {
              var file = $scope.files[i];
              $scope.upload = $upload.upload({
                  url: '/api/v1/attachments/',
                  data: {csrfmiddlewaretoken: csrf, message: 6 },
                  file: file // single file or a list of files. list is only for html5
              }).progress(function (evt) {
                  console.log('progress: ' + parseInt(100.0 * evt.loaded / evt.total) + '% file :' + evt.config.file.name);
              }).success(function (data, status, headers, config) {
                  // file is uploaded successfully
                  console.log('file ' + config.file.name + 'is uploaded successfully. Response: ' + data);
                  data.filename = config.file.name;
                  $scope.attachedFiles.push(data);
              }).error(function (data, status, headers, config) {
                  console.log('fail to upload ' + config.file.name + ' -  response: ' + data.details);
              });
          }
      }
  });

答案 1 :(得分:0)

您的CRSF令牌密钥可能不正确,以下是我的工作方式(仍在制定onBeforeUploadItem()部分):

App.js

require('angular-file-upload');

angular.module('app', [
    'angularFileUpload'
])

控制器

function controller(FileUploader, $q, $cookies, logger) {
    var vm = this;

    function activate() {
        vm.uploader = new FileUploader({
            url: '/api/expense-claim/' + vm.expense.id + '/transport-cost-attachment/',
            headers: {
                'X-CSRFToken': $cookies.get('csrftoken')
            }
        });
        vm.uploader.onBeforeUploadItem = onBeforeUploadItem;
    }

    function onBeforeUploadItem(fileItem) {
        fileItem.formData.push({creator: vm.owner});
        fileItem.formData.push({attachment_file: fileItem.file.name});
    }

    activate();
}

HTML

<input type="file" nv-file-select uploader="vm.uploader"/>
<ul>
    <li ng-repeat="item in vm.uploader.queue">
        Name: <span ng-bind="item.file.name"></span><br/>
        <button ng-click="item.upload()">upload</button>
    </li>
</ul>