How to create a model instance through Serializer without creating models from nested serial series?

I have a model with many links to it:

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, ) ........ 

Many of these models have only two fields with a unique name and image. I create a serializer for each of these models and put them in the TravelSerializer

 class TravelBaseSerializer(DynamicFieldsModelSerializer): owner = UserSerializer(required=False) tags = TagSerializer(many=True) payment = PaymentSerializer() country = CountrySerializer() 

Based on the docs, I override create() and update .
The problem is that when I sent JSON data, Django created each model from nested serializers. But I want to create only a copy of Travel . Also I want to receive and respond to a serialized object not only in the pk field.

UPDATE
I solved this problem, put the code in response. Now I can receive and respond with Serializer data without creating an object. But I think DRF provides a more elegant approach than me. This is my first DRF project, maybe I missed something and there is an easier solution.

+7
django django-rest-framework
source share
2 answers

I decide to override to_internal_value() put it in a custom serailizer and inherit from it all nested serializers:

 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 

Get all pk from it and save it in the create and updated methods:

  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 
+2
source share

I'm not quite sure that I understand what you want to do, but can setting read_only_fields match the Meta class?

 class TravelBaseSerializer(DynamicFieldsModelSerializer): owner = UserSerializer(required=False) tags = TagSerializer(many=True) payment = PaymentSerializer() country = CountrySerializer() class Meta: read_only_fields = ('tags',) 

See this section in the docs.

+1
source share

All Articles