1
votes

I'm experiencing a weird problem where one of my serializers is not getting the context and thus failing.

First, the viewset, I've implemented a list method where I'm filtering orders based on some criteria that is dependent on nested relations in the model.

class OrdersInAgendaViewSet(OrderMixin, viewsets.ReadOnlyModelViewSet):
    queryset = Order.objects.all()
    serializer_class = OrderInAgendaSerializer
    permission_classes = (
        CanManageOrder,
    )

    def list(self, request):
        final_orders = set()
        qs = super(OrdersInAgendaViewSet, self).get_queryset()
        # Get only orders that have lines with products that have no rentals objects
        for order in qs:
            accommodations = False
            lines = order.lines.all()
            for line in lines:
                if line.product.rental:
                    accommodations = True
                    break
            if not accommodations:
                final_orders.add(order.pk)
        qs = qs.filter(pk__in=final_orders)
        serializer = self.serializer_class(qs, many=True)
        return Response(serializer.data)

And now the main Serializer for this ViewSet

class OrderInAgendaSerializer(serializers.ModelSerializer):
    lines = LineForAgendaSerializer(many=True, read_only=True)
    customer = CustomerInOrderSerializer(many=False, read_only=False)
    notes = OrderNoteSerializer(many=True, read_only=True)

    class Meta:
        model = Order
        fields = (
            'id',
            'date_placed',
            'status',
            'payment_status',
            'email_billing',
            'notes',
            'customer',
            'lines',
        )
        extra_kwargs = {'date_placed': {'required': False}}

As you can see I'm using 3 more serializers on this one, the one that is failing is LineForAgendaSerializer:

class LineForAgendaSerializer(serializers.ModelSerializer):
    product = ProductForAgendaSerializer(many=False, read_only=True)
    customers = serializers.SerializerMethodField()

    class Meta:
        model = Line
        fields = (
            'starting_date',
            'ending_date',
            'product',
            'customers',
            'rents',
        )

    def get_customers(self, obj):
        customers = obj.customerinline_set.all()
        session_filter = self.context['request']\
            .query_params.get('session', None)

        if session_filter is not None:
            customers = customers.filter(
                sessions__id=session_filter).distinct()

        serializer = CustomerInLineForAgendaSerializer(customers, many=True, context=self.context)
        return serializer.data

The offending line is in the get_customers method:

session_filter = self.context['request']\
            .query_params.get('session', None)

Checking self.context, is empty, so I get KeyError all the time...

How can I pass the context to this serializer...should it be done from the Viewset (if so how?) or from the OrderInAgendaSerializer (and again, how?)

Thanks

1

1 Answers

3
votes

Yes you should pass context from your viewset.

On this line :

serializer = self.serializer_class(qs, many=True, context={your context})

Alternatively you can user self.get_serializer() method that should work.