Django Rest Framework вложенный многоточечный сериализатор

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

class PositionModel(BaseModel):
    """
    User Position/Designation Model
    """
    name = models.CharField(max_length=255)

    class Meta:
        ordering = ["created_at"]

    def __str__(self):
        return f"{self.name}"


class SuperiorModel(BaseModel):
    """
    Super model for position
    """
    position = models.OneToOneField(PositionModel, on_delete=models.CASCADE, related_name='position_superior')
    superior = models.ManyToManyField(PositionModel, blank=True)

    def __str__(self):
        return f'{self.position.name}'

Сигналы:

@receiver(post_save, sender=PositionModel)
def create_position_instances(sender, instance, created, **kwargs):
    if created:
        SuperiorModel.objects.create(
            position=instance
        )


@receiver(post_save, sender=PositionModel)
def save_position_instances(sender, instance, **kwargs):
    instance.position_superior.save()

Что я хочу здесь, так это создать позицию с превосходящей моделью.

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

{
  "name": "test position",
  "superior": [1,2] # <-- Could be empty array if there is no superior
}

Чтобы, когда я создаю позицию, высшая ценность могла быть создана в SuperiorModel.

Также в методе get я хочу получить те же данные, что и в полезной нагрузке.

Я сделал это следующим образом:

class SuperiorSerializer(serializers.ModelSerializer):
    """
    Superior Serializer
    """

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


class PositionSerializer(serializers.ModelSerializer):
    """
    Serializer for Employee Position
    """

    position_superior = SuperiorSerializer(read_only=True)
    superior = serializers.ListField(write_only=True)

    class Meta:
        model = models.PositionModel
        fields = [
            "id",
            "name",
            "is_active",
            "position_superior",
            "superior",
        ]
        extra_kwargs = {
            "is_active": {"read_only": True},
        }

    @staticmethod
    def update_helper(instance, validated_data):

        superior = validated_data.pop("superior")
        instance.name = validated_data.get("name", instance.name)
        superiors = models.SuperiorModel.objects.get(
            position=instance
        )
        superiors.superior.set(superior)
        instance.save()
  
        return instance

    def create(self, validated_data):

        superior = validated_data.pop("superior")
        position = models.PositionModel.objects.create(
            is_active=True, **validated_data
        )

        superiors = models.SuperiorModel.objects.get(
            position=position
        )
        superiors.superior.set(superior)
        return position

    def update(self, instance, validated_data):
        return self.update_helper(instance, validated_data)

Я не знаю, является ли это оптимизированным или рекомендуемым способом. Если это не так, то любая помощь будет принята с благодарностью.

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