简体   繁体   中英

Django custom file storage

I am writing a dashboard web application with Django. It's an IoT platform where users will be able to review time-series data from sensors. I am working on a feature that will allow a user to extract row data in json or csv formats.

What we have is PSQL + InfluxDB for time-series. We want to have a page in UI where User would generate a file with row data and then could download it after. Also user would be able to review files created before (so we need to keep all generated files and prevent identical to be recreated). We plan to create files with python Celery task and send link to the file to user once file is created.

Part we are struggling with is to find a way to write a model for a file generated.

We have task which:

  1. extract row data and pass it to 2)
  2. generate python file object and pass it to 3)
  3. create and save file on the disk + create save model object

Now we have following model:

# models.py
from orgs.models import Organization

class Report(models.Model):
    name = models.CharField(_('file name'), max_length=128,
                               unique=True)
    file = models.FileField()

    org = models.OneToOneField(
        Organization,
        on_delete=models.PROTECT,
        related_name='org',
        related_query_name='org',
        blank=False,
        null=True,
    )

And task task for 3)

from reports.models import Report
from django.core.files import File
import hashlib


def sha1_name(org_name, uuid, start, end):
    metadata = [org_name, uuid, start, end]
    file_name = hashlib.sha1('_'.join(metadata)).hexdigest()
    return file_name


def crete_and_save_report_object(org, #etc):
    """
    Create report object
    :param path_to_file: path to our file
    :param org: object of model Organization from orgs.models
    :return: report object
    """
    with open(path_to_file) as file:
        report = Report(name=sha1_name(#etc), file=File(file), org=org)
        report.save()

    return report

Any feedback will be appreciated. Thank you for reading.

i have a demo about create qr code and save it in file system which may help:

models.py

def get_time_filename(filename):
    ext = os.path.splitext(filename)[1]
    d = os.path.dirname(filename)
    current_time = datetime.now().strftime('%Y%m%d-%H%M%S-%f')[:-3]
    filename = os.path.join(d, '{}_{}{}'.format(current_time, random.randint(0, 100), ext))
    return filename


def qrcode_cover(instance, filename):
    return 'qr_code/{}'.format(get_time_filename(filename))

class QRCode(models.Model):
    data = models.TextField(verbose_name=u'data')
    image = models.ImageField(upload_to=qrcode_cover,
                              null=True,
                              verbose_name=u'image ')

    class Meta:
        verbose_name = 'QRCode'
        verbose_name_plural = 'QRCode'
        ordering = ('-id',)

    def __str__(self):
        return self.data

views.py

def get_qr_code(data):
    qr_code, is_created = QRCode.objects.get_or_create(data=data)
    if is_created:
        img = qrcode.make(data)
        # ensure media/qr_code/ exist
        file_dir = 'qr_code/'
        media_root = getattr(settings, 'MEDIA_ROOT', None)
        if media_root:
            file_dir = os.path.join(media_root, 'qr_code/')
        if not os.path.exists(file_dir):
            os.makedirs(file_dir)
        # get random filename
        name = qrcode_cover(qr_code, 'data.png')
        # save file to file system
        path = os.path.join(media_root, name)
        img.save(path)
        # save qr_code path to db
        qr_code.image = name
        qr_code.save()
    return qr_code

and here is a download demo which support by apache2 and xsendfile in production:

instance = self.get_object()
if settings.DEBUG:
    response = HttpResponse(instance.file, content_type='application/force-download')
else:
    response = HttpResponse(content_type='application/force-download')
    response['X-Sendfile'] = instance.file.path
response['Content-Disposition'] = 'attachment; filename={}'.format(urlquote(instance.filename))
return response

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM