Как получить доступ к объекту детализации при записи во вложенный сериализатор на действии ModelViewSet?

У меня проблемы с использованием действий для заполнения вложенного сериализатора. У меня есть родительская модель, называемая Allocation, и дочерняя модель, Trade (one-to-many).

У меня есть ModelViewset для Allocation, и я хочу, чтобы у него был метод действия, который позволяет мне отправлять JSON, содержащий список Trades, и создавать их с заполненным отношением к родительской модели.

Как мне получить доступ к объекту родителя или PK на моем TradeSerializer, чтобы я мог заполнить его PrimaryKeyRelatedField?

class AllocationViewSet(ModelViewSet):
    serializer_class = AllocationSerializer
    queryset = Allocation.trades.all()
    lookup_field = "reference_date"

    # The detail=True makes the url allocation/2022-07-25/import_pre_allocation/
    # The 2022-07-25 uniquely identifies my allocation instance.
    @action(detail=True, methods=['POST'])
    def import_pre_allocation(self, request, reference_date=None):
        allocation_obj = self.get_object()

        # here I`m trying to pass my parent object as a context element
        serializer = TradeSerializer(data=request.data, many=True, context={'allocation_pk': allocation_obj.pk})

        if serializer.is_valid():
            for trade in serializer.validated_data:
                trade["allocation"] = allocation_obj
            print(serializer.data)

            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class TradeSerializer(serializers.ModelSerializer):
    quantity = serializers.DecimalField(required=False, max_digits=Trade.TRADE_QUANTITY_MAX_DIGITS, decimal_places=Trade.TRADE_QUANTITY_DECIMAL_PLACES)
    allocation = serializers.PrimaryKeyRelatedField(write_only=True, required=False,queryset=Allocation.objects.all())

    def perform_create(self, serializer):
        # How do I populate my allocation field with the allocation_obj received from context?
        allocation_obj = Allocation.objects.get(pk=self.request.allocation_pk)
        serializer.save(allocation=allocation_obj)
        
    class Meta:
        model = Trade
        fields = ["allocation","quantity"]

Если вы хотите передать родителя и сохранить его в дочернем сериализаторе, вы можете попробовать что-то вроде этого:

class TradeSerializer(ModelSerializer):
  allocation = AllocationSerializer(read_only=True)

  class Meta:
    model = Trade
    exclude = ('id',)

  def create(self, attrs):
    instance = super(TradeSerializer, self).create(attrs)
    instance.allocation = self.initial_data.get('allocation')
    instance.save()

и просто убедитесь, что в вашем представлении передается id распределения

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