Django REST Framework中的子类FileField

时间:2013-03-04 17:56:56

标签: django api django-rest-framework

我有一个带有音频文件的django模型:

class Thing(models.Model):

    audio_file = AudioFileField(    upload_to=audio_dir, blank=True, null=True )
    photo_file = models.ImageField( upload_to=img_dir,   blank=True, null=True )
    ...

其中AudioFileField是执行某些验证的FileField的子类:

class AudioFileField(models.FileField):
    def validate(self, value, model_instance):
        try:
            if not (value.file.content_type == "audio/x-wav" or 
                    value.file.content_type == "audio/amr" or 
                    value.file.content_type == "video/3gpp"):
                raise ValidationError(u'%s is not an audio file' % value)
        except IOError:
            logger.warning("no audio file given")

audio_dir回调设置路径并重命名文件:

def audio_dir(instance, filename):
        return os.path.join("audio", "recording_%s%s" % (
            datetime.datetime.now().isoformat().replace(":", "-"), 
            os.path.splitext(filename)[1].lower() ))

在Django REST框架中,ImageField工作正常,但子类AudioFileField却没有。这是因为子类serializers.FileField不接受关键字参数upload_to

如何通过API公开相同的功能? audio_dir回调对我来说尤其重要。

1 个答案:

答案 0 :(得分:0)

我搜索如何自定义文件字段,我不知道它是否能解决您的问题。如果没有,我会再次搜索它,并告诉我错误。

class Thing(models.Model):
    audio_file = AudioFileField(
        upload_to=audio_dir, 
        blank=True, null=True,
        content_types=['audio/x-wav', 'audio/amr', 'video/3gpp'] 
    )

    ...............

class AudioFileField(models.FileField):
    def __init__(self, *args, **kwargs):
        self.content_types = kwargs.pop("content_types")

        super(AudioFileField, self).__init__(*args, **kwargs)

    def clean(self, *args, **kwargs):        
        data = super(AudioFileField, self).clean(*args, **kwargs)

        audio_file = data.audio_file
        try:
            content_type = audio_file.content_type
            if content_type in self.content_types:
                raise ValidationError(u'{0} is not an audio file'.format(content_type))
            else:
                raise forms.ValidationError(_('Audio file type not supported.'))
        except AttributeError:
            pass        

        return data