Как получить доступ к объекту детализации при записи во вложенный сериализатор на действии 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 распределения