2016-07-19 4 views
7

У меня есть модель с большим количеством ссылок на него:Как создать экземпляр модели через Serializer без создания моделей из вложенных серийных серий?

class Travel(BaseAbstractModel): 

    tags = models.ManyToManyField(
     Tag, 
     related_name='travels', 
     ) 
    owner = models.ForeignKey(
     'users.TravelUser', 
     related_name='travel_owner' 
     ) 
    payment = models.ForeignKey(
     Payment, 
     related_name='travels', 
     ) 
    country = models.ForeignKey(
     Country, 
     related_name='travels, 
     ) 
    ........ 

Многие из этих моделей имеют только два поля с уникальным именем и изображением. Я создаю сериалайзер для каждой из этих моделей и поместить их в TravelSerializer

class TravelBaseSerializer(DynamicFieldsModelSerializer): 

    owner = UserSerializer(required=False) 
    tags = TagSerializer(many=True) 
    payment = PaymentSerializer() 
    country = CountrySerializer() 

На основании документации я переопределить create() и update.
Проблема в том, что когда я отправлял данные JSON, Django создавал каждую модель из вложенных сериализаторов. Но я хочу создать только экземпляр Travel. Также я хочу получить и ответить на сериализованный объект не только pk.

UPDATE
Я решил эту проблему, поставить код в ответ. Теперь я могу получать и отвечать с данными Serializer без создания объекта. Но я думаю, что DRF обеспечивает более элегантный подход, чем я. Это мой первый проект с DRF, возможно, я что-то пропустил, и есть более легкое решение.

ответ

2

решаю переопределение to_internal_value() положить его в пользовательских serailizer и наследует все вложенные сериализаторы от него:

class NestedRelatedSerializer(serializers.ModelSerializer): 

    def to_internal_value(self, data): 
     try: 
      pk = data['pk'] 
     except (TypeError, KeyError): 
     # parse pk from request JSON 
      raise serializers.ValidationError({'_error': 'object must provide pk!'}) 
     return pk 

Получить все pk от него и сохранить в create и updated методами:

def update(self, instance, validated_data): 
     # If don't get instance from db, m2m field won't update immediately 
     # I don't understand why 
     instance = Travel.objects.get(pk=instance.pk) 
     instance.payment_id = validated_data.get('payment', instance.payment_id) 
     instance.country_id = validated_data.get('country', instance.country_id) 
     # update m2m links 
     instance.tags.clear() 
     instance.tags.add(*validated_data.get('tags')) 
     instance.save() 
     return instance 
1

Я m не совсем уверен, что я понимаю, что вы хотите сделать, но может ли установка read_only_fields - это класс Meta, что вам нужно?

class TravelBaseSerializer(DynamicFieldsModelSerializer): 

    owner = UserSerializer(required=False) 
    tags = TagSerializer(many=True) 
    payment = PaymentSerializer() 
    country = CountrySerializer() 

    class Meta: 
     read_only_fields = ('tags',) 

См. this section в документах.

+0

Спасибо, но я попробовал это в первую очередь. Проблема с 'read_only_fields', эти поля не переходят к' validated_data' –

+0

ОК, так что, я думаю, вы хотите это: вы хотите, чтобы, когда ваш сериализатор используется для чтения щенков, он сериализует все связанные поля и когда используется для записи puproses пытается проверить соответствующие поля, но не сохранять их. Пожалуйста, поправьте меня, если я ошибаюсь. – AntoineWDG

+0

да, но мне нужны эти данные в 'validated_data', потому что мне нужно заполнить все поля ссылок в созданной модели' Travel'. Я решаю это, как вы можете видеть в моем ответе. Но я начинаю эту щедрость, потому что я хочу найти какую-то передовую практику для таких целей. Теперь я думаю, что DRF просто не разрешает использовать вложенные сериализаторы для таких целей, по умолчанию –