[Answered ]-How to auto create foreingKey object (python with django)

1👍

serializer.py

class DevicesSerializer(serializers.ModelSerializer):
    group = GroupsSerializer()
    options = OptionsSerializer(many=True)

    class Meta:
        model = models.Devices
        fields = '__all__'

    def create(self, validated_data):
        group_data = validated_data.pop('group')
        options_data = validated_data.pop('options')
        group, _ = models.Groups.objects.get_or_create(**group_data)
        options = [models.Options.objects.create(**option_data) for option_data in options_data]
        device = models.Devices.objects.create(group=group, **validated_data)
        device.options.set(options)
        return device

viewsets.py:

from rest_framework import viewsets
from devices.api import serializers
from devices import models

class DevicesViewsets(viewsets.ModelViewSet):
    serializer_class = serializers.DevicesSerializer
    queryset = models.Devices.objects.all()

    def perform_create(self, serializer):
        serializer.save()

    
class OptionsViewsets(viewsets.ModelViewSet):
    serializer_class = serializers.OptionsSerializer
    queryset = models.Options.objects.all()

class GroupsViewsets(viewsets.ModelViewSet):
    serializer_class = serializers.GroupsSerializer
    queryset = models.Groups.objects.all()

0👍

You are right, the answer is in there. Basically you have to provide a def create(self, validated_data) method to your DevicesSerializer class.

Here is something that could help:

class DevicesSerializer(serializers.ModelSerializer):
    group = GroupsSerializer()
    options = OptionsSerializer(many=True)

    class Meta:
        model = models.Devices
        fields = '__all__'

    def create(self, validated_data):
        options_data = validated_data.pop("options")
        device = models.Devices.objects.create(**validated_data)  # or you can manually pass the fields/data as kwargs

        for option_data in options_data:
            models.Options.objects.create(device=device, **option_data)

        return device

Basically, you need to manually save the base object (Device) and then manually iterate over the options data and create each of them pointing to the newly created device.

Leave a comment