2013-06-05 2 views
0

У меня есть модель файла Джанго, который имеет поле models.FileField и форму, которая используется для загрузки файлов на сервер:загрузки файлов с URLLIB к модели FileField в Django

class UploadFile(model.Model): 
    filename = models.FileField(upload_to='uploads') 
    description = models.CharField(max_length=38, blank=True) 

class UploadFileForm(ModelForm): 
    class Meta: 
     model = UploadFile 
     fields = ('filename', 'description') 

Это как вид функция выглядит следующим образом:

def upload_file(request): 
    if request.method == 'POST': 
     form = UploadFileForm(request.POST, request.FILES) 
     if form.is_valid(): 
      new_file = form.save() 

Теперь я хотел бы иметь сценарий питона, который использует только стандартную библиотеку для загрузки файлов модели UploadFile с помощью функции просмотра выше. Однако этот код не работает, потому что запрос POST не имеет метода FILES.

import urllib, urllib2 
data = urllib.urlencode({'filename': open(uploadfile, "rb"), 
         'description': 'upload test'}) 
post_req = urllib2.Request(upload_file_url, data) 
result = urllib2.urlopen(post_req) 

Как я могу добавить метод FILES к запросу POST для загрузки файлов с использованием сценария python? Я также пытался написать другую функцию представления, которая не использовала форму, но она также не работает.

+0

Я буду использовать УПП для копирования файлов через пока я не могу получить некоторую помощь с этим issue –

ответ

4

Чтобы посмотреть, работает ли ваш вид Джанго, вы можете проверить его с помощью браузера:

<FORM action="{{ upload_file_url }}" 
     enctype="multipart/form-data" 
     method="POST"> 
    Description: <INPUT type="text" name="description" value="upload test"><BR> 
    File to upload: <INPUT type="file" name="filename"><BR> 
    <INPUT type="submit" value="Send"> 
</FORM> 

Это complicated повторить его программно, используя только STDLIB.

Для загрузки файлов в качестве multipart/form-data можно использовать requests library:

import requests 

response = requests.post(upload_file_url, 
         files={'filename': open(uploadfile,'rb'), 
           'description': 'upload test'}) 
print response.content 

Или urllib2 и poster библиотеки:

import urllib2 

import poster.encode 
import poster.streaminghttp 

opener = poster.streaminghttp.register_openers() 

params = {'filename': open(uploadfile,'rb'), 'description': 'upload test'} 
datagen, headers = poster.encode.multipart_encode(params) 
response = opener.open(urllib2.Request(upload_file_url, datagen, headers)) 
print response.read() 
+0

Спасибо, мне, возможно, придется использовать библиотеку запросов в будущем. В настоящий момент я использую urllib.urlencode для кодирования файлов postscript, так как это все, что мне нужно, но оно не работает для двоичных файлов ... –

+0

@ MigueldeVal-Borro: urlencode() создает данные x-www-form-urlencoded, но Файл FileField от django ожидает multipart/form-data. Он должен * не * работать для любого файла. Ваше мнение работает с формой html, которую я опубликовал? – jfs

+0

@JF Себастьян Да, у меня была аналогичная форма, которая сработала. Мне также нужно сделать то же самое с stdlib, поэтому я отправляю что-то вроде 'urllib.urlencode ({" filename ":" plot.ps "," data ": f.read()," description ":" test upload "}) 'и определить функцию представления, которая хранит данные в модели и файле на диске. –

0

Это не так просто, не так ли? request не имеет метода FILES (который не является методом, является словарем). Проблема в том, что Django не распознает файлы, если в запросе нет Content-Type:multipart/form-data.

Обратите внимание, что FILES будет содержать только данные, если метод запроса был POST, а сообщение, отправленное на запрос, имело enctype = "multipart/form-data". В противном случае FILES будет пустым словарным объектом.

Здесь вы можете увидеть, как запрос, как это выглядит: What should a Multipart HTTP request with multiple files look like?

https://docs.djangoproject.com/en/dev/ref/request-response/

Поэтому в основном то, что вы должны сделать, это добавить это поле в запросе, который вы строите и отправить это к джанго позже.

Вы можете ознакомиться с этими страницами из документа django, чтобы получить дополнительную информацию об этом, и будет здорово, если вы сможете понюхать или посмотреть, как запрос отправляется на django, чтобы вы могли узнать, чего не хватает.

https://docs.djangoproject.com/en/dev/ref/forms/api/

Поскольку это не легко/прямой ответ на этот вопрос, я надеюсь, что это может поставить вас в правильном направлении.

Удачи вам!

+0

Я догадываюсь, что мне не хватает, как добавить ФАЙЛЫ к запросу, созданному с помощью urllib2. –

+0

Хорошо, вам не нужно добавлять словарь 'FILES' в запрос. Вам нужно будет надлежащим образом выполнить запрос и когда Django проанализирует его, он заполнит словарь 'request.FILES' сам по себе. –

Смежные вопросы