0

I have a model Invoice:

class Invoice(Model):
    datetime = DateTimeField(..)
    paid = BooleanField(..)

I want to get queryset of n latest Invoices where paid = True but I want to include paid = False Invoices if there are some between n latest paid Invoices.

So I want minimal queryset of latest Invoices where there is exactly n of them paid.

Example:

We have 8 invoices ordered by ("-created","-id"):

datetime = 15.04.2018 14:00
paid = True
______________
datetime = 15.04.2018 13:00
paid = True
______________
datetime = 14.04.2018 14:00
paid = True
______________
datetime = 14.04.2018 14:00
paid = True
______________
datetime = 13.04.2018 14:00
paid = True
______________
datetime = 13.04.2018 14:00
paid = False
______________
datetime = 13.04.2018 14:00
paid = True
______________
datetime = 13.04.2018 14:00
paid = False
______________

If I want a queryset of 6 latest paid Invoices I will get all of them except the last one. The queryset will include 6th Invoice even if it's not paid yet.

latest_n_paid = Invoice.objects.get(paid=True)[:n]
first_paid_from_latest_n_paid = latest_n_paid.last()
queryset = Invoice objects.filter(datetime__gte=first_paid_from_latest_n_paid.datetime)

This would not work because it would return all Invoices since the last one has the same datetime as last paid Invoice.

Do you know what to do?

EDIT

I would like to do this on a database level instead of looping over queryset if possible.

Milano
  • 18,048
  • 37
  • 153
  • 353
  • 1
    I'm not sure I completely understand the expected behavior here. You want to query for the latest N invoices that are `paid`. How do the ones that are `paid=False` come into play here? Maybe you can add an example of expected vs actual output? – k-nut Jul 25 '18 at 09:27

1 Answers1

0

I have a solution :

query_set = Invoice.objects.order_by('-paid','-datetime')[:n]