Philipp S.
Philipp S.

Reputation: 981

Django: How to filter a subset in a querset?

How can I filter the elements in a subset?

class Order(models.Model):
    user                = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
    ...

class Bill(models.Model):
    order           = models.ForeignKey(Order, blank=True, null=True, on_delete=models.SET_NULL))
    billdate        = models.DateTimeField(default=timezone.now)
    payed           = models.BooleanField(default=False)
    ...

For example:

    order = Orders.objects.all()
    order[0].bill_set # Should return only 3 bills
    order[1].bill_set # Should return only 3 bills
    order[2].bill_set # Should return only 3 bills
    order[3].bill_set # Should return only 3 bills

will return all Bills. But I just want to get the latest 3 elements, ordererd by billdate. How can I do this?

I want to use the result in Django Rest Framework in my view:

class OrderSerializer(serializers.ModelSerializer):

    class Meta:
        model = Order

        fields = (
            'id'
            'bill_set'
        )


class AffiliateOrderViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):

    serializer_class = OrderSerializer


    def get_queryset(self):
        return Order.objects.filter(bill_set__filter_somehow_only_the_last_3_entries_ordered_by_date)

Any idea?

Upvotes: 0

Views: 300

Answers (2)

Ngoc Pham
Ngoc Pham

Reputation: 1458

You can simple add atribute in model Order

class Order(models.Model):
    user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)

    def get_number_of_last_bill(self, number):
        return self.bill_set.order_by("billdate")[:number]

And in queryset, call this:

order = Orders.objects.all()

order[0].get_number_of_last_bill(3) 
order[1].get_number_of_last_bill(3) 

in your serializer, you can add field like this:

class BillSerializer(serializers.ModelSerializer):

    class Meta:
        model = Bill

        fields = (
            'id',
            'payed'
        )

class OrderSerializer(serializers.ModelSerializer):
    number_of_last_bill = serializers.SerializerMethodField()

    class Meta:
        model = Order

        fields = (
            'id',
            'bill_set',
            'number_of_last_bill',

        )
    def get_number_of_last_bill(self, obj):
        return BillSerializer(obj.get_number_of_last_bill(3), many=True).data

Upvotes: 1

Pavan kumar
Pavan kumar

Reputation: 515

You can simply do this

def get_queryset(self):
        return Order.objects.all()[0].bill_set.order_by('billdate')[:3]

or you can do this also

def get_queryset(self):
    q1 = Order.objects.all()[0].bill_set
    q2 = q1.order_by('billdate')[0:3]
    return q2

Upvotes: 0

Related Questions