I want to be able to download something I uploaded in the admin right next to the upload field.
Right now I upload a pdf using this method:
class OrderAdminForm(forms.ModelForm):
invoice_file = forms.FileField(required = False, label = "invoice PDF")
class Meta:
model = Order
fields = ["product", "manufacturer", "order_date",]
def clean_invoice_file(self):
cleaned_data = super().clean()
if "invoice_file" in self.changed_data:
print("invoice_file file was uploaded")
cleaned_data["invoice"] = cleaned_data["invoice_file"].read()
return cleaned_data
def clean(self):
cleaned_data = super().clean()
if "invoice_file" in self.changed_data:
self.instance.invoice = self.cleaned_data["invoice"]
return cleaned_data
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
list_display = ["product", "manufacturer", "order_date",]
list_filter = ["product", "manufacturer",]
form = OrderAdminForm
change_form_template = "download_invoice_button.html"
def save_model(self, request, obj, form, change):
obj.user = request.user
return super().save_model(request, obj, form, change)
def file_size(self, obj):
return f"""{len(obj.file)/1024:,.2f} KByte"""
def response_change(self, request, obj):
if "_download_invoice" in request.POST:
response = FileResponse(obj.get_file)
response['Content-Type'] = 'application/pdf'
response["Content-Disposition"] = f"""attachment; filename="{obj.get_file_name}" """
return response
else:
return super().response_change(request, obj)
and I added a download button in the download_invoice_button.html
like this:
{% extends 'admin/change_form.html' %}
{% block submit_buttons_bottom %}
{{ block.super }}
<div class="submit-row">
<input type="submit" value="Download Invoce" name="_download_invoice">
</div>
{% endblock %}
But now my change_form
looks like this:
And I would like to achieve this look:
How can this be done?
For completness - The model:
class Order(Comment):
product = ForeignKey(Product, on_delete=CASCADE)
manufacturer = CharField(max_length=128)
order_date = DateField(default = timezone.now, editable=True)
invoice = BinaryField(editable=True, blank=True)
@property
def get_file_name(self):
return f"""{self.manufacturer}_{self.order_date}.pdf"""
@property
def get_file(self):
return io.BytesIO(self.invoice)