Метод 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 и этих двух сериализаторов. и после этого ваше представление сделает все остальное.