Хорошо, поэтому я сначала проголосовал и реализовал решение Narendra, прежде чем понял, что оно не может работать, поскольку javascript не может установить значения input type = "file". Увидеть:
http://www.w3schools.com/jsref/prop_fileupload_value.asp
Но вот решение, которое работает:
- Отделите остальную часть формы от файлов, которые необходимо загрузить.
- Всегда сохраняйте файл (или запускайте проверку, чтобы убедиться, что файл должен быть сохранен) и сохраняйте во временную модель.
- В шаблоне есть скрытое поле с идентификатором экземпляра временной модели, поэтому, если вы измените файл, изменение будет распространено. Вы можете получить дополнительные файлы, сохраненные на вашем сервере, но вы можете очистить их извне.
- Когда форму можно сохранить без каких-либо файлов, сохраните ее, привяжите сохраненные файлы к исходной модели и удалите промежуточную загруженную модель файла.
Хорошо, вот эскиз процедуры, которая работает для меня на примере, где вы пытаетесь сохранить PDF-файл книги с адресом электронной почты (выбранным в качестве электронных писем, иногда не подтверждающих) автора.
models.py
class Book(models.Model):
pdf = models.FileField("PDF", upload_to="books/")
author_email = models.EmailField("Author Email")
class TempPDF(models.Model):
pdf = models.FileField("PDF", upload_to="books/")
forms.py
from project_name.app_name.models import Book, TempPDF
from django.forms import ModelForm
from django.contrib.admin.widgets import AdminFileWidget
class BookForm(ModelForm):
class Meta:
model = Book
exclude = ['pdf',]
class TempPDFForm(ModelForm):
class Meta:
model = TempPDF
widgets = dict(pdf = AdminFileWidget)
# The AdminFileWidget will give a link to the saved file as well as give a prompt to change the file.
# Note: be safe and don't let malicious users upload php/cgi scripts that your webserver may try running.
views.py
def new_book_form(request):
if request.method == 'POST':
## Always try saving file.
try:
temp_pdf_inst = TempPDF.objects.get(id=request.POST.has_key('temp_pdf_id'))
except: ## should really catch specific errors, but being quick
temp_pdf_inst = None
temp_pdf_form = TempPDFForm(request.POST, request.FILES, instance=temp_pdf_inst, prefix='temp_pdf')
if temp_pdf_form.is_valid() and len(request.FILES) > 0:
temp_pdf_inst = temp_pdf_form.save()
temp_pdf_id = temp_pdf_inst.id
book_form = BookForm(request.POST, prefix='book')
if book_form.is_valid(): # All validation rules pass
book = book_form.save(commit=False)
book.pdf = temp_pdf_inst.pdf
book.save()
if temp_pdf_inst != None:
temp_pdf_inst.delete()
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
book_form = BookForm() # An unbound form
temp_pdf_form = TempPDFForm()
temp_pdf_id = None
return render_to_response('bookform_template.html',
dict(book_form = book_form,
temp_pdf_form = temp_pdf_form,
temp_pdf_id = temp_pdf_id)
)
bookform_template.html
<table>
{{ book_form }}
{{ temp_pdf_form }}
<input type="hidden" name="temp_pdf_id" value="{{ temp_pdf_id }}">
</table>