Создайте экземпляр из сериализатора без сохранения его в db

в контексте создание модели django:

# Creates potato and saves a row to db
spud = Potato.objects.create(...)

# Also creates a potato instance, but doesn't hit db yet.
# Could call `spud.save()` later if/when we want that.
spud = Potato(...)

на фабрика мальчик у нас также есть аналогия для этого Djangoism

# Returns a saved instance
spud = PotatoFactory.create()

# Returns an instance that's not saved
spud = PotatoFactory.build()

на база отдыха v3.3.2, я не могу найти аналогию. Возможно ли это?

serializer = PotatoSerializer(data=...)

# creates the instance and saves in db
serializer.create(serializer.validated_data)

Я могу написать свой собственный, что-то вроде этого:

class PotatoSerializer:
    ...
    def build(self, validated_data):
        return self.Meta.model(**validated_data)

но это перетаскивание, чтобы не иметь его на базовом сериализаторе, я что-то пропустил?

3 ответов


от https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/serializers.py#L811-L846 (комментарии опущены):

def create(self, validated_data):
    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.objects.create(**validated_data)

сериализатор create() метод представляет собой довольно тонкую обертку вокруг модели create() метод.

плохая новость в том, что вы правы, нет ярлыка сериализатора только для памяти:

class PotatoSerializer:
    ...
    def build(self, validated_data):
        return self.Meta.model(**validated_data)

хорошая новость заключается в том, что вы можете вырезать среднего человека и назвать модель напрямую:

Potato(**validated_data)

по умолчанию Serializer сохранить в базе данных. Однако, если вы хотите протестировать против проверки, простой вызов is_valid будет делать и избегать сохранения в базе данных.

Я в основном догадываюсь, так как ваш вопрос не очень ясен относительно вашей цели.


в вашем PotatoSerializer вам нужно переопределить метод Create. что-то вроде этого:--2-->

class PotatoSerializer:
    ...
    class Meta:
        ...

    def create(self, validated_data):
        # and here you change the default behavior of the serializer
        return Potato(**validated_data)
            # instead of
            # return Potato.objects.create(**validated_data)