【问题标题】:'ngFileUpload' and Django Rest Framework'ngFileUpload' 和 Django Rest 框架
【发布时间】:2016-03-18 06:29:44
【问题描述】:

您好,我有一个使用 AngularJS 作为前端和 Django Rest Framework 作为后端的 Web 应用程序。一切都很顺利,除了当我在 ngFileUpload 的上传函数的 data 参数中传递一个 json 值并在 django rest 框架中打印 request.data 时,它会导致

{ 'principal_master[id]': ['1'], 'file': [<InMemoryUploadedFile: adgc.jpg (image/jpeg)>], 'username': ['dsadasd'] }

什么时候会发生

{ 'principal_master' : '{ "id": "1"}', 'file': [<InMemoryUploadedFile: adgc.jpg (image/jpeg)>], 'username': ['dsadasd']  }

这是我在前端 HTML 上的代码:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script type="text/javascript" src="https://angular-file-upload.appspot.com/js/ng-file-upload.min.js"></script>
<div ng-controller="MyCtrl">
    <form name="myForm" >
        <fieldset>
          <legend>Upload on form submit</legend>
          Username:
          <input type="text" name="userName" ng-model="username" size="31" required>
          <i ng-show="myForm.userName.$error.required">*required</i>
          <br>Photo:
          <input type="file" ngf-select ng-model="picFile" name="file"    
                 accept="image/*" ngf-max-size="2MB" required
                 ngf-model-invalid="errorFile">
          <i ng-show="myForm.file.$error.required">*required</i><br>
          <i ng-show="myForm.file.$error.maxSize">File too large 
              {{errorFile.size / 1000000|number:1}}MB: max 2M</i>
          <img ng-show="myForm.file.$valid" ngf-thumbnail="picFile" class="thumb"> <button ng-click="picFile = null" ng-show="picFile">Remove</button>
          <br>
          <button ng-disabled="!myForm.$valid" 
                  ng-click="uploadPic(picFile)">Submit</button>
          <span class="progress" ng-show="picFile.progress >= 0">
            <div style="width:{{picFile.progress}}%" 
                ng-bind="picFile.progress + '%'"></div>
          </span>
          <span ng-show="picFile.result">Upload Successful</span>
          <span class="err" ng-show="errorMsg">{{errorMsg}}</span>
        </fieldset>
        <br>
    </form>
</div>

这是我在前端 JS 上的代码: var app = angular.module('myApp', ['ngFileUpload']); app.config(function($interpolateProvider, $httpProvider) { // 更改模板标签 $interpolateProvider.startSymbol('[['); $interpolateProvider.endSymbol(']]'); });

app.controller('MyCtrl', function($scope, Upload, $timeout){
    $scope.uploadPic = function(file) {
    file.upload = Upload.upload({
      url: 'http://192.168.0.50:8000/api/people/v1/principals/add/',
      data: {username: $scope.username, principal_master : '{ "id": "1"}' file: file},
    });

    file.upload.then(function (response) {
      $timeout(function () {
        file.result = response.data;
      });
    }, function (response) {
      if (response.status > 0)
        $scope.errorMsg = response.status + ': ' + response.data;
    }, function (evt) {
      // Math.min is to fix IE which reports 200% sometimes
      file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
    });
    }
});

这是我在后端的基本代码:

#python
import json

#Django Core
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.db.models import Q

#Rest Framework
from rest_framework.parsers import FileUploadParser, FormParser, MultiPartParser
from rest_framework.response import Response
from rest_framework import status
from rest_framework.decorators import api_view, parser_classes

#test_people app
from .serializers import *
from test_people.decorators import token_required

@api_view(['POST'])
# @parser_classes((FileUploadParser,))
@parser_classes((FormParser, MultiPartParser))
@csrf_exempt
@token_required
def add(request):
    #print(request.data)
    if request.method == 'POST':
        print("-------------")
        print(request.data)
        print(request.data['principal_master'])
        print(type(request.data['principal_master']))
        return

【问题讨论】:

  • 为什么你有 json 字符串作为 id 而不是实际的对象。
  • 因为该键的值是另一个用于继承和 DRY 目的的序列化程序
  • 您的请求在浏览器的网络选项卡中是什么样的?
  • 这个:{ 'principal_master[id]': ['1'], 'file': [], 'username': [' dsadasd'] }

标签: angularjs django django-rest-framework ng-file-upload


【解决方案1】:

我可以使用 arrayKey: '' 更新选项和 MultiPartParser 来解决这个问题。

我的控制器:

Upload.upload({
  url: '/my/api/file/',
  data: {
      file: file
  },
  arrayKey: '',
}, ...)

我的看法:

class FileViewSet(viewsets.ModelViewSet):
    queryset = File.objects.all()
    serializer_class = FileSerializer
    parser_classes = (parsers.FormParser, parsers.MultiPartParser,)

【讨论】:

    猜你喜欢
    • 2015-01-04
    • 2015-08-07
    • 2014-04-21
    • 2015-04-26
    • 2015-07-16
    • 2020-07-27
    • 2018-06-12
    • 1970-01-01
    相关资源
    最近更新 更多