【问题标题】:Convert (and validate) file added in django admin转换(并验证)在 django admin 中添加的文件
【发布时间】:2019-08-02 17:32:31
【问题描述】:

我正在开发一个使用自定义问候语的 Django 项目(例如在语音邮件中)。整个功能都实现了,我创建了一个自定义模型:

class Greeting(models.Model):
    audio_file = models.FileField(upload_to='greetings/')
    description = models.CharField(max_length=128)
    uploaded_at = models.DateTimeField(auto_now_add=True)

我想做的下一件事是确保上传的文件具有所有预期的属性(WAV 文件、有一个频道、比特率低等)。但我什至不知道从哪里开始。这些文件只能通过 django admin 添加。在常规的 FormView 中,我会在 View 中使用服务器端验证,然后才将其添加到模型中。如何在 django admin 中进行操作?

总结一下我希望我的应用程序做什么:

1) 在 django admin 中向模型添加文件 2) 服务器检查文件属性,如果不满足要求,则尝试将其转换为正确的格式 3) 如果文件格式正确,则仅保存对象。

【问题讨论】:

    标签: python django


    【解决方案1】:

    您需要使用自定义表单注册 ModelAdmin。 ModelAdmin 有一个表单属性,默认设置为 forms.ModelForm 类,您可以通过将该属性分配给您的 Admin 类来替换它。

    # app_dir/admin.py
    from django.contrib import admin
    
    from .forms import GreetingAdminForm
    from .models import Greeting
    
    @admin.register(models.Greeting)
    class GreetingAdmin(admin.ModelAdmin):
        form = GreetingAdminForm
        readonly_fields = ['uploaded_at']
    

    您需要在 forms.py 中定义您的 GreetingAdminForm。使用自定义验证逻辑。 我这样做的方法是添加一个带有覆盖的 audo_file 字段的 ModelForm 并添加了验证器。您可以查看 django 文档以编写验证逻辑 here

    您可能想使用文件扩展名验证,并在表单上添加一个 clean_{fieldname} 方法。 clean_{fieldname} 方法不接受任何参数,但该方法的返回值必须替换clean_data 中的现有值。您将需要一个适合您需要的外部库,接受您打算允许的音频格式,并以所需格式输出处理后的文件。清理特定属性的文档是 here

    # app_dir/forms.py
    from django import forms
    from django.core.exceptions import ValidationError
    
    from .validators import validate_file_extension
    from .models import Greeting
    
    class GreetingAdminForm(forms.ModelForm):
        audio_file = forms.FileField(validators=[validate_file_extension])
    
        def clean_audio_file(self):
            data = self.cleaned_data
            processed_audio_file = None
            # audio file processing logic goes here, 
    
            if  not processed_audio_file:
                raise ValidationError('error message')
            data['audio_file'] = processed_audio_file
            return data
    
        class Meta:
            model = Greeting
            fields = [
                'audio_file',
                'description'
            ]
    
    
    # app_dir/validators.py
    def validate_file_extension(value):
        # validate file extension logic here, 
    

    您可以找到文件扩展名验证的示例 here

    解决这个问题的另一个角度也可能是 - 编写子类 FileField 的自定义表单字段,您可以找到有关编写自己的字段 here 的文档,此类应覆盖 w 方法 validate() - 处理验证逻辑,以及准备输出可用的 python在你的 python 代码中

    【讨论】:

    • 感谢您的回复!您的解决方案很好,但有一些错误:-两个语法错误,在类 GreetingAdminForm 和未封闭的 quoute 类 Meta 'audio_file' 之后没有“:” - 必须注册新的 GreetingAdmin 您可以编辑您的答案,以便我可以接受给别人?
    • 很高兴能帮上忙,抱歉语法错误 - 已修复!
    猜你喜欢
    • 2011-10-07
    • 2011-06-12
    • 2018-10-13
    • 2021-02-01
    • 2020-01-07
    • 1970-01-01
    • 2014-09-08
    • 2017-05-18
    • 2012-11-11
    相关资源
    最近更新 更多