Метод Post для передачи данных нескольким сериализаторам моделей

Я новичок в Django и у меня есть объект json, данные которого должны быть разделены и сохранены в 3 разных моделях Django. Я пытаюсь понять, правильно ли я делаю это, используя файл представления и сериализаторы в Django.

Объект json, который я получаю в файл views, выглядит следующим образом:

[
    {
        "contact_entry": 
        {
            "employee_name" : "Tom Hanks",
            "employee_type" : "Full-time permanent"
        },
        "address" : 
        {
            "line1": "1435 Manhattan Ave",
            "line2": "Apt 123",
            "city": "New York",
            "state": "New York",
            "country":"US",
        },
        "phone_number" : 
        {
            "work_number": "9901948626"
            "home_number": "9908847555"
        }
    }
]

У меня есть три модели django, как показано ниже:

class ContactEntry(models.Model):
    employee_name = models.CharField(max_length=128)
    employee_type = models.CharField(max_length=128)
    
class Address(models.Model):
    contact_entry = models.ForeignKey(ContactEntry, on_delete=models.CASCADE)
    line1 = models.CharField(max_length=128)
    line2 = models.CharField(max_length=128)
    city = models.CharField(max_length=128)
    state = models.CharField(max_length=128)
    country = models.CharField(max_length=128)

class PhoneNumber(model.Model):
    contact_entry = models.ForeignKey(ContactEntry, on_delete=models.CASCADE)
    work_number = models.IntegerField(max_length=10)
    home_number = models.IntegerField(max_length=10)

У каждого из них есть ModelSerializer, как показано ниже:

class ContactEntrySerializer(serializers.ModelSerializer):
    class Meta:
        model = ContactEntry
        fields = '__all__'

class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address
        fields = '__all__'

class PhoneNumberSerializer(serializers.ModelSerializer):
    class Meta:
        model = PhoneNumber
        fields = '__all__'

Я определил один сериализатор (унаследованный от serializers.serializer), который объединяет вышеупомянутые 3 сериализатора, как показано ниже:

class CombinedSerializer(serializers.Serializer):
    contact_entry = ContactEntrySerializer()
    phone_number = PhoneNumberSerializer()
    address = AddressSerializer()

Метод post в моем представлении выглядит так, как показано ниже:

class CombinedContactView(APIView):

    def post(self, request, *args, **kwargs):

        # Validate JSON data with the serializer
        serializer = CombinedSerializer(data=request.data, many=True)
        serializer.is_valid(raise_exception=True)
        validated_data = serializer.validated_data.pop()

        contact_entry_data = validated_data['contact_entry']
        address_data = validated_data['address']
        phone_number_data = validated_data['phone_number']

        # Create model for contact book entry
        contact_entry_model = ContactEntry(**contact_entry_data)
        contact_entry_model.save()

        # Create model for address
        address_data['contact_entry'] = contact_entry_model
        address_model = Address(**address_data)
        address_model.save()

        # Create model for phone_number
        phone_number_data['contact_entry'] = contact_entry_model
        phone_number_model = PhoneNumber(**phone_number_data)
        phone_number_model.save()

        return HttpResponse(status=201)

Приведенный выше код на самом деле работает нормально. Я вижу, что объект contact_entry создан, а адрес и телефон_numbers правильно созданы (со связью внешнего ключа с объектом contact_entry). Однако меня беспокоит, что я делаю это окольными путями с большим количеством ненужного кода в моем файле представлений. Есть ли более простой способ сделать это?

если вы измените свои сериализаторы на эти, то все будет в порядке:

class ContactEntrySerializer(serializers.ModelSerializer):
    class Meta:
        model = ContactEntry
        fields = '__all__'


class AddressSerializer(serializers.ModelSerializer):
    contact_entry = ContactEntrySerializer(required=False)

    class Meta:
        model = Address
        fields = '__all__'


class PhoneNumberSerializer(serializers.ModelSerializer):
    contact_entry = ContactEntrySerializer(required=False)

    class Meta:
        model = PhoneNumber
        fields = '__all__'

заметьте, что я изменил contact_entry на AddressSerializer и PhoneNumberSerializer на required=False так что вы можете пройти валидацию contact_entry и этих двух сериализаторов. и после этого ваше представление сделает все остальное.

Вернуться на верх