Загрузить файл с помощью Angular и Django
Итак, у меня есть проблема, для которой я не могу найти решение. Я разрабатываю приложение, используя Django, где мой интерфейс должен быть в angular-js. Теперь я могу отображать формы, а также публиковать данные из форм, но я не знаю, как загрузить файл с помощью этих форм.
Это мой код:
в 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']
Я получаю сообщение об ошибке "файл_отбора" не найден в MultiValueDict: {}
Вероятно, проблема в том, что при отправке моего почтового запроса не отправляются все метаданные.... Пожалуйста, помогите мне с этим, я потратил целый день в поисках решения, но безрезультатно.
PS: для некоторых политик ограничения я не могу использовать Djangular, поэтому, пожалуйста, дайте мне решения, которые не используют djangular. Спасибо
Редактировать: ** Применение свойств файла к json, который получает сервер, тоже не работает **
4 ответа
У меня была такая же проблема. Я нашел эффективное решение для отправки файлов в Django Forms с помощью Angular $http.
ДИРЕКТИВА
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)
})
}
ФОРМА ВИДА НА ДЖАНГО
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})
Используйте приведенный ниже фрагмент, чтобы вы могли отправлять обычные данные вместе с данными файла из 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.
});
};
Теперь вы получите select_file
под request.FILES
и другие данные внутри request.POST
по вашему мнению, Джанго.
Сочетание ранних постов с правильными угловыми функциями.
(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);
Я настоятельно рекомендую использовать сторонние плагины, такие как ngUpload или fileUploader для достижения этой цели. То, что вы делаете на клиенте, выглядит неправильно.
Также обратитесь к этой теме SO по загрузке файлов angularjs