首页 > 解决方案 > 如何创建自定义 FileField 来修改 Django 中上传的文件

问题描述

我想在上传文件时修改文件的内容。我有许多模型使用了几个 FileFields,它们都需要这种行为,所以我不想save()在每个模型上使用信号或覆盖模型。我想创建一个自定义 FileField 来处理这种行为。

我试图通过扩展 FileField 并覆盖该pre_save()方法来做到这一点。我能够读取文件内容,但是当我写入文件时它保持不变。下面是一个基本的例子。

字段.py

from django.db.models import FileField

class CustomFileField(FileField):
    def pre_save(self, model_instance, add):
        file = super().pre_save(model_instance, add)
        file.write(b'foo')
        return file

模型.py

from django.db import models
from fields import CustomFileField

class MyModel(models.Model):
    my_field = CustomFileField(upload_to='files')

标签: djangodjango-models

解决方案


我没有制作自定义 FileField,而是采用以下方法创建一个没有逻辑的自定义字段和一个在save()方法中修改文件的抽象模型。我仍然觉得这个逻辑应该属于自定义字段,这很hacky。但它确实有效。

字段.py

from django.db.models import FileField

class CustomFileField(FileField):
    pass

模型.py

from django.db import models
from fields import CustomFileField

class CustomFileFieldModel(models.Model):
    class Meta:
        abstract = True

    def save(self, force_insert=False, force_update=False, using=None,
         update_fields=None):
    super().save(force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields)

    fields = self._meta.get_fields()

    for field in fields:
        if field.__class__ == CustomFileField:

            file = getattr(self, field.name)

            with file.open(mode='w') as f:
                f.write('foo')

class MyModel(CustomFileFieldModel):
    my_field = CustomFileField(upload_to='files')

推荐阅读