Reputation: 3
I'm using Django Rest Framework with two models, a service and a message, where a service can have many messages. Using a foreign key.
class Service(models.Model):
servicename = models.TextField(blank=False)
sender = models.TextField(blank=False)
class Message(models.Model):
service = models.ForeignKey(Service, related_name='messages', on_delete=models.CASCADE)
description = models.TextField(blank=False)
The only usecase is where you enter a service, which is nested to take input for the message. Therefore, service will create both the service and the message at the same time. If the service doesn't exist, it will be created. If it does exist, the message will point towards the service.
As it is a one-to-many, it seems like I need many=True
in my serializer, which is undesirable as there is never a usecase where two messages are inputted simultaneously, and also means the web UI will not work since lists are not supported.
class MessageSerializer(serializers.ModelSerializer):
class Meta:
model = Message
fields = ('description',)
class ServiceSerializer(serializers.ModelSerializer):
messages = MessageSerializer(many=True)
class Meta:
model = Service
fields = ('servicename', 'sender', 'messages')
def create(self, validated_data):
messages_data = validated_data.pop('messages')
print(messages_data)
service, created = Service.objects.get_or_create(
servicename=validated_data['servicename'],
sender=validated_data['sender']
)
Message.objects.create(service=service, **messages_data[0])
return service
So, is it possible to have a nested serializer with only one object during input? Removing many=True results in a typical AttributeError, which I've come to understand means it is not allowed since the reverse of one-to-many means it needs to have the ability to take multiple objects.
Thanks
Upvotes: 0
Views: 3481
Reputation: 3091
I would suggest for you to use two different fields for this.
Something like this:
class ServiceSerializer(serializers.ModelSerializer):
messages = MessageSerializer(many=True, read_only=True)
message = MessageSerializer(write_only=True)
So, for input - you will have only write_only attribute which won't be serialized on the way out - only when you post ( you can decide with required
attribute to make it optional )
And vice versa for messages - only read only.
And you handle it accordingly in create method.
Upvotes: 1