In my Django View file, I need to generate a CSV file from a list of tuples and store the CSV file into the FileField of my model.
class Bill(models.Model): billId = models.IntegerField() bill = models.FileField(upload_to='bills')
I searched on this site, and found some posts such as Django - how to create a file and save it to a model's FileField?, but the solutions can help me.
I need the CSV file to be stored in 'media/bills/' fold, and I hope the CSV file can be deleted together with the Bill object in the database.
I tried the following codes, but it cannot meet my requirements. For each file, it will generate two files 'output.csv' and 'output_xxesss.csv'. At the two files cannot be deleted by calling 'Bill.objects.all().delete()'.
path = join(settings.MEDIA_ROOT, 'bills', 'output.csv') print path f = open(path, 'w+b') f.truncate() csvWriter = csv.writer(f) csvWriter.writerow(('A', 'B', 'C')) for r in rs: print r csvWriter.writerow(convert(r)) bill = Bill() bill.billId = 14 bill.bill.save('output.csv', File(f)) bill.save()
I tried the following codes, but it can not delete the file by calling 'Bill.objects.all().delete()'.
bill = Bill() bill.billId = 14 bill.bill.name = 'bills/output.csv' bill.save()
Deleting an instance would not delete the associated file. You may consider using
signals to be precise
pre_delete. You can write a receiver where in you can delete the associated file.
from django.dispatch import receiver from django.db.models.signals import pre_delete @receiver(pre_delete) def func_name(sender, instance, **kwargs): your logic
You can find documentation here.
If anyone comes to this post like me and is wondering how to save a csv file directly into a
models.FileField i recommend this way:
import csv from io import StringIO from django.core.files.base import ContentFile row = ["Name", "Location", "Price"] csv_buffer = StringIO() csv_writer = csv.writer(csv_buffer) csv_writer.writerow(row) csv_file = ContentFile(csv_buffer.getvalue()) bill.bill.save('output.csv', csv_file)