文件上传 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 进行多部分文件上传