简体   繁体   English

Django自定义文件存储

[英]Django custom file storage

I am writing a dashboard web application with Django. 我正在用Django编写仪表板Web应用程序。 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. 我正在开发一项功能,该功能将允许用户提取jsoncsv格式的行数据。

What we have is PSQL + InfluxDB for time-series. 我们拥有的是针对时间序列的PSQL + InfluxDB。 We want to have a page in UI where User would generate a file with row data and then could download it after. 我们希望在UI中有一个页面,用户可以在其中生成带有行数据的文件,然后再下载。 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. 我们计划使用python Celery任务创建文件,并在文件创建后将指向该文件的链接发送给用户。

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)
  2. generate python file object and pass it to 3) 生成python文件对象并将其传递给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) 和任务任务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 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 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: 这是一个下载演示,该演示在生产环境中受apache2和xsendfile支持:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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