模型:
class Photo(models.Model): img = models.ImageField(upload_to='photos/',max_length=254) text = models.CharField(max_length=254,blank=True)
串行:
class PhotoSerializer(serializers.ModelSerializer): class Meta: model = Photo fields = ('img','text')
观点:
class PhotoViewSet(viewsets.ModelViewSet): queryset = Photo.objects.all() serializer_class = PhotoSerializer photo_router = DefaultRouter() photo_router.register(r'photo',PhotoViewSet)
网址:
urlpatterns = [ url(r'^admin/',admin.site.urls),url(r'^api/',include(photo_router.urls)),]
POST和GET在/ api / photo /中运行良好
我之前问过类似的问题,我当然肯定,问题出在前端,使用AngularJS,我也是第一次使用AngularJS.但我想现在,我的服务器应用可能有问题.
角度代码:
var app = angular.module('myApp',['ngRoute','angularFileUpload']); app.config(function ($routeProvider) { $routeProvider .when('/',{ templateUrl: 'http://127.0.0.1:8000/static/js/angular/templates/home.html' }) }); app.config(['$httpProvider',function($httpProvider) { $httpProvider.defaults.xsrfCookieName = 'csrftoken'; $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken'; }]);
GET控制器运行良好,我收到了所有图像:
app.controller('getController',['$scope','$http',function($scope,$http){ $http.get('/api/photo/').success(function(data){ $scope.photos = data; }).error(function(data) { $scope.photos = data; }); }]);
对于文件上传,我使用了this guide
以下是指南中的代码:
app.directive('fileModel',['$parse',function ($parse) { return { restrict: 'A',link: function(scope,element,attrs) { var model = $parse(attrs.fileModel); var modelSetter = model.assign; element.bind('change',function(){ scope.$apply(function(){ modelSetter(scope,element[0].files[0]); }); }); } }; }]); app.service('fileUpload',['$http',function ($http) { this.uploadFileToUrl = function(file,uploadUrl){ var fd = new FormData(); fd.append('file',file); $http.post(uploadUrl,fd,{ transformRequest: angular.identity,headers: {'Content-Type': undefined} }) .success(function(){ }) .error(function(){ }); } }]); app.controller('myCtrl','fileUpload',fileUpload){ $scope.uploadFile = function(){ var file = $scope.myFile; console.log('file is ' ); console.dir(file); var uploadUrl = "/api/photo/"; fileUpload.uploadFileToUrl(file,uploadUrl); }; }]);
<div ng-controller = "myCtrl"> <input type="file" file-model="myFile"/> <button ng-click="uploadFile()">upload me</button> </div>
POST 07001 400 (Bad Request)
in responce:
img: [“No file was submitted.”]
请至少帮助理解我的问题所在,在我的REST或Angular中.我怎么调试这个?我花了一整天时间来寻找解决方案.我想我显然不明白REST api需要看起来如何.
UPD
我正在尝试使用ng-file-upload,仍然有400个响应状态.
我决定是序列化程序的问题,我在视图中覆盖POST方法,但我认为我做错了:
class PhotoViewSet(viewsets.ModelViewSet): queryset = Photo.objects.all() serializer_class = PhotoSerializer def post(self,request,format=None): serializer = PhotoSerializer(data=request.DATA) if serializer.is_valid(): serializer.save() return Response(serializer.data,status=status.HTTP_201_CREATED) return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
以下是来自Web工具的完整请求数据:
General
Request URL:07001
Request Method:POST
Status Code:400 Bad Request
Remote Address:127.0.0.1:8000
Response Headers
Allow:GET,POST,HEAD,OPTIONS
Content-Type:application/json
Date:Wed,09 Mar 2016 14:46:44 GMT
Server:WSGIServer/0.2 CPython/3.4.3
Vary:Accept,Cookie
X-Frame-Options:SAMEORIGIN
Request Headers
Accept:application/json,text/plain,/
Accept-Encoding:gzip,deflate
Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Content-Length:16635
Content-Type:multipart/form-data; boundary=—- WebKitFormBoundarytci4JfMISlMXwzFw
Cookie:sessionid=f5nyqdclupgi44zyqbmo3gkenum9k0cj; csrftoken=E0DuVDs5KrV0rSMuD5wC86RPO0QP4AgT
Host:127.0.0.1:8000
Origin:07004
Referer:07005
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/47.0.2526.106 Safari/537.36
X-CSRFToken:E0DuVDs5KrV0rSMuD5wC86RPO0QP4AgT
Request Payload
——WebKitFormBoundarytci4JfMISlMXwzFw
Content-Disposition: form-data; name=”file”; filename=”2.jpg”
Content-Type: image/jpeg
——WebKitFormBoundarytci4JfMISlMXwzFw–
解决方法
您需要在视图中添加相关的parser_classes
,并覆盖perform_create函数以从POST数据中获取文件:
class PhotoViewSet(viewsets.ModelViewSet): queryset = Photo.objects.all() serializer_class = PhotoSerializer parser_classes = (MultiPartParser,FormParser,) def perform_create(self,serializer): serializer.save(img=self.request.data.get('img')) # do note that at this time `text` information is not available
因为,我们发布FormData,我们使用以下解析器(link):
parser_classes = (MultiPartParser,)
另外,请注意serializer.is_valid()抛出错误,因为它没有获取post数据中的img字段.您需要设置img而不是文件字段:
fd.append('img',file);