2👍
✅
Solution 1:
The fields in validated data is renamed with the source attribute. You can use the renamed attribute in create
method of serializer.
For nested serializers, seems the validated data contains OrderedDict
. You can convert it to regular Dict
, and can get the rule id.
class ProgramSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(max_length=32)
description = serializers.CharField(style={'base_template': 'textarea.html'})
rules = PrioritySerializer(source='priority_set', many=True)
def create(self, validated_data):
rules_data = validated_data.pop('priority_set')
program_obj = Program.objects.create(**validated_data)
priority = 0
for rule in rules_data:
rule_obj = Rule.objects.get(pk=dict(rule)["rule"]["id"])
priority += 1
Priority.objects.create(program=program_obj, rule=rule_obj, priority=priority)
return program_obj
Solution 2:
You can make rules
with source name priority_set
as read_only
and can extract it from request data.
class ProgramSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(max_length=32)
description = serializers.CharField(style={'base_template': 'textarea.html'})
rules = PrioritySerializer(source='priority_set', many=True, read_only=True)
def create(self, validated_data):
rules_data = self.context["request"].data["rules"]
program_obj = Program.objects.create(**validated_data)
priority = 0
for rule in rules_data:
rule_obj = Rule.objects.get(pk=rule["rule_id"])
priority += 1
Priority.objects.create(program=program_obj, rule=rule_obj, priority=priority)
return program_obj
You will need to pass request context to serializer
serializer = ProgramSerializer(data=request.data, partial=True, context={"request": request})
Solution 3:
Add related_name
in program
Foreign key in Priority
model.
program = models.ForeignKey(Program, related_name="rule", on_delete=models.CASCADE)
Rename rules
field in ProgramSerializer
to something else e.g. rule
, and remove source.
class ProgramSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(max_length=32)
description = serializers.CharField(style={'base_template': 'textarea.html'})
rule = PrioritySerializer(many=True)
def create(self, validated_data):
rules_data = validated_data.pop('rule')
program_obj = Program.objects.create(**validated_data)
priority = 0
for rule in rules_data:
rule_obj = Rule.objects.get(pk=dict(rule)["rule"]["id"])
priority += 1
Priority.objects.create(program=program_obj, rule=rule_obj, priority=priority)
return program_obj
Now you will be able to post and retrieve data with rule
key. You can rename it something else as appropriate.
Source:stackexchange.com