Я пытаюсь следовать https://simpleisbetterthancomplex.com/tutorial/2016/08/01/how-to-upload-files-with-django.html, но мне не удается найти свою ошибку:
models.py :
class PurchaseOrderRequest(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, db_index=True)
request_object = models.CharField(max_length=80) # Should be a ForeignKey later
order_summary = models.CharField(max_length=80)
vendor = models.CharField(max_length=80)
currency = models.CharField(max_length=40, choices=CURRENCY_CHOICES, default="USD")
quote = models.FileField(upload_to='uploads/po-quotes/%Y/%m')
date_updated = models.DateTimeField(auto_now=True)
date_uploaded = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.order_summary
forms.py
class PurchaseOrderRequestForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
'request_object',
'order_summary',
Row(
Column('vendor', css_class='form_group col-md-4 mb0'),
Column('currency', css_class='form_group col-md-4 mb0'),
Column('quote', css_class='form_group col-md-4 mb0'),
css_class='form_row'
),
Submit('submit', 'Request')
)
class Meta:
model = PurchaseOrderRequest
fields = '__all__'
labels = {
'order_summary': _('Summary of ordered goods'),
'quote': _('Quotation'),
}
help_texts = {
'order_summary': _('Example: Construction - Kitchen - Electrical Appliances'),
}
widgets = {
}
Моя задача - цитата FileField.
Шаблон HTML выглядит следующим образом:
po_request. html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}
{% endblock title %}
{% block content %}
<h1>Request a Purchase Order</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% crispy form %}
</form>
{% endblock content %}
Мой Google-Fu указал, что мне нужно добавить опцию enctype = "multipart / form-data" для работы FileFields.
views.py
def createRequest(request):
if request.method == 'POST':
form = PurchaseOrderRequestForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('/', pk=form.id)
else:
form = PurchaseOrderRequestForm()
return render(request, 'po_request.html', {'form': form })
Мой Google-Fu указал, что мне нужно добавить request.FILES, чтобы поймать FileField. Поскольку это ModelForm, form.save () должен - в соответствии с инструкциями - сохранить вложение в путь upload_to.
Я вижу форму, она выглядит красиво и красиво на основе crispy_forms. Независимо от размера выбранного файла (файлы .deb и .jpg, от 300 КБ до 330 МБ) размер POST браузера составляет около 12 КБ.
[09/Mar/2020 15:34:00] "POST /purchaseorders/request/ HTTP/1.1" 200 11225
[09/Mar/2020 16:51:33] "POST /purchaseorders/request/ HTTP/1.1" 200 11120
Модель работает нормально через интерфейс администратора, и я могу загрузить файлы оттуда - но почему он не работает со "стандартного" веб-интерфейса?
Спасибо, MN