使用Angular和Django上传文件

3 投票
4 回答
8289 浏览
提问于 2025-04-18 14:50

我遇到了一个问题,找不到解决办法。我正在用Django开发一个应用程序,前端需要用AngularJS。现在我可以渲染表单,也能提交表单里的数据,但我不知道怎么通过这些表单上传文件。

这是我的代码:

在urls.py文件里

url(r'^getter/$', TemplateView.as_view(template_name = "upload.html"))
url(r'^getter/test/', views.test, name = "thanks.html")

在views.py文件里

def test(request):
   upload_form = uploadform(request.POST, request.FILES)
   data = json.loads(request.body)
   file_path = data.path

在forms.py文件里

select_file = forms.FileField(label = "Choose File")

在我控制器里的js文件中

myapp.controller('abc', function ($scope, $http)
$scope.submit = function(){
var file = document.getElementById('id_select_file').value
var json = {file : string(file)}
$http.post('test/',json)
...success fn....
...error fn...

};

现在的问题是,如果在我的视图里我这样做

f = request.FILES['select_file']

我会收到错误信息 'select_file' 在MultiValueDict中未找到: {}

可能的问题是,我发送POST请求的方式没有发送所有的元数据……请帮帮我,我今天整整一天都在找解决办法,但没有结果。

附注:由于一些限制政策,我不能使用Djangular,所以请给我一些不使用Djangular的解决方案。谢谢

编辑:**将文件属性应用到服务器接收的json上也不行**

4 个回答

-1

我强烈建议你使用一些第三方插件,比如 ngUpload 或者 fileUploader 来实现这个功能。你在客户端做的事情看起来不太对。

另外,你可以参考 这个关于AngularJS文件上传的讨论

0

这是一些早期帖子,里面包含了正确的Angular函数。

(function(app){
   app.controller("Name_of_Controller", function($scope, $http){
      $scope.submit = function(){
         var fd = new FormData();
         datas = $("#formID").serializeArray();
         for( var i = 0; i < datas.length; i++ ) {
            fd.append(datas[i].name, datas[i].value);
         };
        fd.append("selected_file", $("#file_id")[0].files[0])
        fd.append("type", "edit");
        url = "/results/",
        $http.post(url, fd, {
            headers: {'Content-Type': undefined },
            transformRequest: angular.identity
        }).then(function (response) {
            console.log(response.data)
        }).catch(function (err) {});;
    };
});
})(App_name);
1

使用下面的代码片段,这样你就可以从Angular发送普通数据和文件数据到Django了。

$scope.submit = function(){
    var fd = new FormData();
    datas = $("#FormId").serializeArray();
    // send other data in the form
    for( var i = 0; i < datas.length; i++ ) {
         fd.append(datas[i].name, datas[i].value);
        };
    // append file to FormData
    fd.append("select_file", $("#id_select_file")[0].files[0])
    // for sending manual values
    fd.append("type", "edit");
    url = "getter/test/",
    $http.post(url, fd, {
        headers: {'Content-Type': undefined },
        transformRequest: angular.identity
    }).success(function(data, status, headers, config) {
        // this callback will be called asynchronously
        // when the response is available
    }).
    error(function(data, status, headers, config) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
        });
};

现在在你的Django视图中,你会在 request.FILES 里找到 select_file,而其他数据会在 request.POST 里。

3

我之前也遇到过同样的问题。我找到了一种有效的方法,可以用Angular的$http把文件发送到Django表单。

指令

app.directive("filesInput", function() {
  return {
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) {
      elem.on("change", function(e) {
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      })
    }
  }
});

HTML

<form ng-submit="send()" enctype="multipart/form-data">
    <input type="text" ng-model="producer.name" placeholder="Name">
    <input type="file" files-input ng-model="producer.video">
</form>

控制器

$scope.send = function(){
    var fd = new FormData();
    fd.append('video', $scope.producer.video[0]);
    fd.append("name", $scope.producer.name);

    $http({
        method: 'POST',
        url: '/sendproducer/',
        headers: {
          'Content-Type': undefined
        },
        data: fd,
        transformRequest: angular.identity
    })
    .then(function (response) {
      console.log(response.data)
    })
}

Django视图表单

class ProducerView(View):

    def dispatch(self, *args, **kwargs):
        return super(ProducerView, self).dispatch(*args, **kwargs)

    def post(self, request):
        form = ProducerForm(data = request.POST, files = request.FILES or None)
        if form.is_valid():
            form.save()
            return JsonResponse({"status": "success", "message": "Success"})
        return JsonResponse({"status": "error", "message": form.errors})

撰写回答