Django - how to create a file and save it to a model's FileField?
You want to have a look at FileField and FieldFile in the Django docs, and especially FieldFile.save().
Basically, a field declared as a FileField
, when accessed, gives you an instance of class FieldFile
, which gives you several methods to interact with the underlying file. So, what you need to do is:
self.license_file.save(new_name, new_contents)
where new_name
is the filename you wish assigned and new_contents
is the content of the file. Note that new_contents
must be an instance of either django.core.files.File
or django.core.files.base.ContentFile
(see given links to manual for the details).
The two choices boil down to:
from django.core.files.base import ContentFile, File
# Using File
with open('/path/to/file') as f:
self.license_file.save(new_name, File(f))
# Using ContentFile
self.license_file.save(new_name, ContentFile('A string with the file content'))
Django : generate a file then save it in a FileField
When running self.contract.save(filename, f)
add the save
parameter through as shown below.
This will not run the Contract
instance save method, which is causing your recursion.
self.contract.save(filename, f, save=False)
I would also recommend using with ...
when opening files so they don't stay open. Shown below:
def save(self, *args, **kwargs):
filename = self.generate_contract()
with open(filename, "r") as f:
self.contract.save(filename, f)
return super().save(*args, **kwargs)
Django - How to automatically create a .docx file and save it to a model's FileField?
I am assuming you are using docxtpl and python docx. docx can save in byte like objects.
Something like this should work:
import io
def populate_docx(self, template_path, context):
draft_lease = DocxTemplate(template_path) /// Gets the template
draft_lease.render(context) /// Populates the template
file_bytes = io.BytesIO()
draft_lease.save(file_bytes)
file_bytes.seek(0)
self.lease_draft.save('Lease #12345', ContentFile(file_bytes.read()))
How to Create and Save File in Django Model
It seems like your view is quite close to doing what you want. In your model, add a FileField
for order_file
:
class Orders(models.Model):
...
order_file = models.FileField(upload_to='path/to/storage/', null=True, blank=True)
Then in your view, save the BytesIO
object you've created to the order_file
field in the Orders
object with the correct reference_id
by wrapping it in a File
object:
from django.core.files import File
def docjawn(request):
reference = request.POST.get('Reference_IDs')
manifest = Manifests.objects.all().filter(reference__reference=reference)
order = Orders.objects.get(reference=reference)
# Generate doc file
...
doc_io = io.BytesIO()
doc.save(doc_io)
doc_io.seek(0)
# Save the BytesIO to the field here
order.order_file.save("generated_doc.docx", File(doc_io))
response = HttpResponse(doc_io.read())
response["Content-Disposition"] = "attachment; filename=generated_doc.docx"
response["Content-Type"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
return response
Related Topics
Execute a File with Arguments in Python Shell
"Line Contains Null Byte" in CSV Reader (Python)
Plotting a Decision Boundary Separating 2 Classes Using Matplotlib's Pyplot
How Does Perspective Transformation Work in Pil
How to Source Virtualenv Activate in a Bash Script
Writing a Dict to Txt File and Reading It Back
Python Typeerror: Not Enough Arguments for Format String
How to Dynamically Create Derived Classes from a Base Class
How to Find the Groups of Consecutive Elements in a Numpy Array
How to Filter Rows in Pandas by Regex
Django: Improperlyconfigured: the Secret_Key Setting Must Not Be Empty
Flask SQLalchemy Query, Specify Column Names