DRF - добавить аргумент в Model.save (...) - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть модель Invoice и в переопределенном методе Invoice.save() есть аргумент recalculate.

Я хочу, чтобы Invoice пересчитывался всегда, кроме случаев, когда он создан с использованием своего сериализатора.

Возможно ли это?

Сериализаторы используют create, поэтому я не уверен, как это сделать. (Это ModelSerializer)

1 Ответ

0 голосов
/ 18 февраля 2020

Вы можете создать миксин для переопределения метода create и передачи аргумента recalculate без вызова super().create(), а затем использовать его в сериализаторе: например, InvoiceSerializer(CreateMixin, serlializers.ModelSerializer)

class CreateMixin:
    def create(self, validated_data, recalculate):
        raise_errors_on_nested_writes('create', self, validated_data)

        ModelClass = self.Meta.model

        info = model_meta.get_field_info(ModelClass)
        many_to_many = {}
        for field_name, relation_info in info.relations.items():
            if relation_info.to_many and (field_name in validated_data):
                many_to_many[field_name] = validated_data.pop(field_name)

        try:
            instance = ModelClass(**validated_data)
            '''
            your custom logic with recalculate argument
            '''


        except TypeError:
            tb = traceback.format_exc()
            msg = (
                    'Got a `TypeError` when calling `%s.%s.create()`. '
                    'This may be because you have a writable field on the '
                    'serializer class that is not a valid argument to '
                    '`%s.%s.create()`. You may need to make the field '
                    'read-only, or override the %s.create() method to handle '
                    'this correctly.\nOriginal exception was:\n %s' %
                    (
                        ModelClass.__name__,
                        ModelClass._default_manager.name,
                        ModelClass.__name__,
                        ModelClass._default_manager.name,
                        self.__class__.__name__,
                        tb
                    )
            )
            raise TypeError(msg)

        # Save many-to-many relationships after the instance is created.
        if many_to_many:
            for field_name, value in many_to_many.items():
                field = getattr(instance, field_name)
                field.set(value)

        return instance
...