2

I'm working on a Django project that utilizes customized greetings (like in voicemail). The whole functionality is implemented, i have created a custom model:

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)

The next thing that i wanted to do is to make sure that the uploaded file has all the expected properties (is a WAV file, has one channel, has low bitrate etc). But i don't even know where to start. These files will be only added via django admin. In regular FormView i would utilize server-sided validation in View, and only then add it to model. How to do it in django admin?

To summarize what i expect my app to do:

1) Add file to a model in django admin 2) Server checks file properties, and if requirements are not met, tries to convert it to proper format 3) If the file is in proper format, only then it saves the object.

Jacek
  • 171
  • 2
  • 12

1 Answers1

3

You need to register a ModelAdmin with a custom form. ModelAdmin has a form property which is by default set to forms.ModelForm class, you can replace that by assigining that property to your Admin class.

# 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']

Than you need to define your GreetingAdminForm in forms.py. with custom validation Logic. The way I would do it is add a ModelForm with overridden audo_file field with added validators. You can check the django documentation for writing your validation logic here

Probaly you want to use file extension validation, and add a clean_{fieldname} method on the form. The clean_{fieldname} method does not take any arguments but the return value of this method must replace the existing value in cleaned_data. You will need an external library that suits your needs, accepts audio formats that you intend to allow, and outputs processed file in desired format. Docs on cleaning specific attribiutes are 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, 

you can find a example of file extension validation here

Another angle to approach this could be also - writing a custom form field which subclasses the FileField,you can find documentation on writing your own field here, this class should override w methods validate() - which handles validation logic, and to python where you would prepare output to be available in your python code

  • Thank you for your response! Your solution is good, but there are a few mistakes: -Two syntax errors, no ":" after class GreetingAdminForm and unclosed quoute in class Meta 'audio_file' -It's mandatory to register the new GreetingAdmin Can you edit your answer so i can accept it for others? – Jacek Mar 13 '19 at 16:55
  • I`m glad I helped, sorry for syntax errors - fixed them ! – Maciej Słoniewski Mar 14 '19 at 13:11