user3774763
user3774763

Reputation: 127

File Upload AngularJS and Django: TypeError at /uploaded_file uploadFile() missing 1 required positional argument: 'request'

I am doing a file upload using angularjs as my front-end and django as my back-end. In my AngularJS, I can successfully detect what the file I've uploaded is. However, I can't seem to pass uploaded file to django. This is the error that I've got

TypeError at /uploaded_file uploadFile() missing 1 required positional argument: '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})

Upvotes: 1

Views: 250

Answers (1)

Iain Shelvington
Iain Shelvington

Reputation: 32244

You first need to create a ModelForm for your UploadFile model

forms.py:

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

Then you need to update your view to use this form

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

Upvotes: 1

Related Questions