How to add a validation to a model serializer so that it ensures at least one of two fields are passed for sure?

I have made a model in Django which includes two fields, let's call them file and code. file is a file field and code is a character field. I've set them both as blank=True and null=True. Set the validation in model by overriding the clean() method to check if file and code both don't exist, it throws a validation error saying at least one should be passed. Called full_clean() in the overridden save() method.

This approach does allow me to add this sort of at least one validation for these two fields on the model level and even through the admin panel.

But, in the serializer, or while hitting the API, it doesn't really throw any error if I don't pass both, that's probably coz my model basically says both aren't required individually.

What I tried doing is that I have overridden the validate() method in the serializer, it's a model serializer btw. In the overridden validate() method I added the check as:

if file not in data and code not in data:
    raise serializers.ValidationError("At least one of the two must be passed.")

What should I do instead? Even a change in the model might help but it should keep that validation in the admin panel as well.

I've listed the fields in Meta but I also tried creating fields for these two explicitly in the serializer and setting required=False and then handling custom validation in the validate() method as suggested in some other threads.

Any help is appreciated! Thanks!

  • Keep your model-level validation (fine for admin and database integrity).

  • In your serializer, override validate() to check for both fields missing.

  • Make the serializer fields required=False so they can be omitted by clients.

  • Call full_clean() from your save() and/or rely on serializer validation separately.

    example :

    This way, both admin and API validations enforce the rule

class MyModelSerializer(serializers.ModelSerializer): file = serializers.FileField(required=False) code = serializers.CharField(required=False)

def validate(self, data):
    file = data.get('file')
    code = data.get('code')
    if not file and not code:
        raise serializers.ValidationError("At least one of 'file' or 'code' must be provided.")
    return data

class Meta:
    model = MyModel
    fields = ['file', 'code', ...]
Вернуться на верх