文件上传 AngularJS 和 Django:/uploaded_file uploadFile() 处的 TypeError 缺少 1 个必需的位置参数:“请求”

Posted

技术标签:

【中文标题】文件上传 AngularJS 和 Django:/uploaded_file uploadFile() 处的 TypeError 缺少 1 个必需的位置参数:“请求”【英文标题】:File Upload AngularJS and Django: TypeError at /uploaded_file uploadFile() missing 1 required positional argument: 'request' 【发布时间】:2020-04-18 09:32:12 【问题描述】:

我正在使用 angularjs 作为我的前端和 django 作为我的后端进行文件上传。在我的 AngularJS 中,我可以成功检测到我上传的文件是什么。但是,我似乎无法将上传的文件传递给 django。这是我遇到的错误

/uploaded_file 处的类型错误 uploadFile() 缺少 1 个必需的位置参数:'request'`。

Environment:

Request Method: GET
Request URL: http://127.0.0.1:8000/uploaded_file

Django Version: 2.1.1
Python Version: 3.7.4
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'webapp',
 'rest_framework',
 'restAPI',
 'django_filters')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')    

Traceback:

File "C:\Users\John\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Users\John\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\John\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\John\app\views.py" in uploadFile
  769.     return render(request, uploadFile(), 'form': form)

Exception Type: TypeError at /uploaded_file
Exception Value: uploadFile() missing 1 required positional argument: 'request'

.html:

<body ng-app="myApp" ng-controller="appCtrl">
     <input type="file" id="file" name="files" accept="text/*" 
            data-url="file" class="inputfile_upload" select-ng-files
            ng-model="uploadedFile"/>
     <label for="file"> <span id="chooseFile"></span>Upload a file!</label>
     <button id="submitBtn" type="submit" ng-click="upload()">Upload</button>
</body>

directive.js:

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

controller.js:

var app = angular.module('myApp', [])
app.controller('appCtrl', function ($scope, $rootScope, $http, fileUploadService)

    $scope.upload = function() 
       var file = $scope.uploadedFile; 
       console.log('file is ' );
       console.dir(file);

       var uploadUrl = "/uploaded_file";
       fileUploadService.uploadFileToUrl(file, uploadUrl);
       $http(
             method:'POST',
             url: '/uploaded_file'
       ).then(function successCallback(response) 
         console.log("success");
       , function errorCallback(response)
         console.log("failed");
       )
    ;

service.js:

app.factory('fileUploadService', function ($rootScope, $http) 
    var service = ;
    service.uploadFileToUrl = function upload(file, uploadUrl)
        var fd = new FormData();
        fd.append('file', file);
        $http.post(uploadUrl, fd, 
            transformRequest: angular.identity,
            headers: 'Content-Type': undefined
        ).then(function successCallback(response)
            console.log("Files added");
        , function errorCallback(response)
            console.log("Files not successfully added");
        )    
    
    return service;
);

urls.py:

urlpatterns = [
url(r'^uploaded_file$', uploadFile, name='uploadFile'),
    url(r'^admin/', admin.site.urls),
]
if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

views.py:

def uploadFile(request):
if request.method == 'POST':
    # When files are submitted to the server, the file data ends up placed in request.FILES.
    form = UploadFile(request.POST, request.FILES)
    if form.is_valid():
        # file is saved
        form.save()
        messages.success(request, 'File uploaded successfully!', extra_tags='alert')
        return JsonResponse("status": "success", "message": "Success")
    return JsonResponse("status": "error", "message": form.errors)
else:
    form = UploadFile()
return render(request, uploadFile(), 'form': form)

【问题讨论】:

为什么将uploadFile() 作为render 的第二个参数?这个参数可能应该是要渲染的模板的名称 @IainShelvington 所以我只需要return render(request, 'form': form) ? render 需要传递一个模板来渲染。当方法为 GET 时,您希望响应是什么? @IainShelvington 假设读取文件并执行一些操作。 不知何故,您使用 GET 请求请求视图,我认为您不打算这样做...您能在浏览器开发工具中看到该请求吗?这个 GET 来自哪里? 【参考方案1】:

您首先需要为您的UploadFile 模型创建一个ModelForm

forms.py:

class UploadFileForm(forms.ModelForm):
    class Meta:
        model = UploadFile
        fields = '__all__'

那么你需要更新你的视图来使用这个表单

def uploadFile(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            messages.success(request, 'File uploaded successfully!', extra_tags='alert')
            return JsonResponse("status": "success", "message": "Success")
        return JsonResponse("status": "error", "message": form.errors, status=400) # Add status=400 here so you get an error when the form is invalid
    else:
        return HttpResponseNotAllowed(['POST']) # Return method not allowed here as a GET does not make sense

【讨论】:

以上是关于文件上传 AngularJS 和 Django:/uploaded_file uploadFile() 处的 TypeError 缺少 1 个必需的位置参数:“请求”的主要内容,如果未能解决你的问题,请参考以下文章

使用 AngularJS 和 SpringMVC 进行多部分文件上传

无法上传文件,php和angularjs

Angularjs - 使用 php 上传文件

Python Django-REST框架和Angularjs的文件夹结构

webAPI+angularJS文件上传和下载

Angularjs如何上传多部分表单数据和文件?