2

I have a Django application in which I there are a number of projects. Each project can have a number of budgets, and every time a new budget is added to a project, the existing budgets for that project should have their version_number incremented by one. The 'current' budget should be the budget whose version_number is 0- so when trying to 'get' the current budget for use elsewhere in the code, I am doing things like:

budgetInstance = Budget.objects.get(project = project, version_number = 0)

However, it seems that somehow, some of the projects have ended up with a number of budgets whose version_number is 0, so it appears that some of the projects in the database seem to have several 'current budgets'...

I know that I will need to fix the logic for how the versioning is done, so that no two budgets can have the same version_number, but for now, I just want to get the most recent budget for each project in the database.

Each Budget object has attributes such as: project_id, version_number, id, presentation_date, etc.

So I now want to filter the budgets that have been returned when I filtered by version_number = 0) by their presentation_date field. As I understand, I would do this using min(), but I can't seem to get this working...

I tried following the accepted answer at: Find oldest/youngest datetime object in a list, and ran the following in the shell:

mostRecentBudget = min(date for date in budgets.dates if date < now)

But I got a TypeError, which said:

TypeError: 'instancemethod' object is not iterable

Why is this? How can I search through the list of Budgets in a given Project, for the one with the most recent presentation_date field value?

Community
  • 1
  • 1
Noble-Surfer
  • 3,052
  • 11
  • 73
  • 118
  • You're going to need to give more information. What is `budgets` and `budgets.dates` here? And why can't you use the db to order this query? – Daniel Roseman Jan 24 '17 at 12:38

1 Answers1

4

You can filter on Date[Time]Fields with __lt[e], __gt[e] and date[time] objects. Then, use latest(field_name):

from django.utils import timezone

now = timezone.datetime.now()
Budget.objects.filter(
    project=project, version_number=0, 
    presentation_date__lte=now  # p_d less than or equal now
).latest('presentation_date')

Unlike last, but very much like get, this will raise an ObjectDoesNotExist if the QuerySet is empty.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • Hey, thanks for your answer. I'm getting a `DoesNotExist` error message, as you mentioned I might, but I'm not sure why...? Why would the queryset be empty? If I run: `testPrjBdgtsv0 = testPrjBdgts.filter(version_number = 0)`, and then `testPrjBdgtsv0`, I get the following output: `[, , ... ]` so clearly the queryset is not empty...? – Noble-Surfer Jan 24 '17 at 13:06
  • Then it shouldn't raise an exception. Are you sure you call latest on the exact same queryset? The qs in my example has a couple more filters. – user2390182 Jan 24 '17 at 13:14
  • I'm typing it exactly as you have written it in your answer there, but there's something a bit unusual happening when I type it: after typing the `__lte=`, the cursor moves back to the start of the line, so as I continue typing `now)`, that is all overwriting what was written at the start of the line... – Noble-Surfer Jan 24 '17 at 13:21
  • It actually seems to have really messed up the input in the shell somehow... When I started typing on that line, the prompt said: `now[58]`, rather than `In [57]:` as it had on the previous input line... and every line after that (if I press Enter) just has `... :` I'm not sure why this is? – Noble-Surfer Jan 24 '17 at 13:24
  • @someone2088 `ctrl + c` is your friend in the shell. `...` means the statement you are typing is not finished yet – user2390182 Jan 24 '17 at 13:24
  • Ok, so I exited that weird input, and did it again- I still get the `DoesNotExist` message you said I might – Noble-Surfer Jan 24 '17 at 13:28
  • I am sure I call `latest` on the exact same queryset.... I've even manually retrieved the `budgets` individually to look at them... and I can see that they have differing values for their `version_date` properties... – Noble-Surfer Jan 24 '17 at 13:46
  • And when you call latest on said queryset, it raises an exception? I am confused now with `version_date` and `presentation_date`. You will figure it out! ;) – user2390182 Jan 24 '17 at 13:50