Hi, I’m new to Python Django. I want to create a generatedfield that stores the # of days between today and another date field in my model. Currently I have the following:
Side note: I see that you enclosed your code between the three backticks, but didn’t post the code indented appropriately, and also enclosed the lines between single backticks. (I’ve taken the liberty of fixing the post.)
This expression: expression=now().date() - F('Date_Received') is not going to work the way you think it’s going to work. Since “now” is a Django function and not a database function, the now().date() function call will be initialized when the model is imported when the system is started. It is not going to be evaluated when an instance is saved.
And, even if you use the right function for the database, I still don’t think this is going to work as you are wanting it to. A persisted field is stored in the database, it isn’t calculated on an as-needed basis. Once it is saved, that’s the value it’s going to be.
I believe the appropriate solution would be for you to annotate the value when you are writing your query.
Following you advice…in my queryset I want to first calculate the date diff between today and a date field in the db, then based on the result classify the orders in queue into different buckets (e.g., ‘< 1 week’, ‘1-2 weeks’).
I know Django doesn’t allow <> in the queryset and you have to use __lt, __gt. But how would that work with a calculation such as ExpressionWrapper(datetime.date.today()-F(‘Date_Received’), output_field=fields.DateField())?
There are a couple different ways of doing this, depending upon what you’re going to do with this information after you’ve gathered it.
How many “buckets” do you need to create?
Is it limited to some specific number, or are you going to create as many as needed?
Is every bucket going to be the same size?
What are you going to do with these buckets after identifying their members?
Hi Ken,
I want to have 4 buckets: “< 1 week”, “1-2 weeks”, “2-3 weeks”, “> 3 weeks”. Each bucket may have different number of orders depending on the data.
I want to do a group by query based on these buckets and create charts using the query result.
You can use the Case / When functions in an annotate to assign the row into a “bucket”, then you can either aggregate this data by bucket in a query, or do it in Python with the query results - it all depends upon what you’re trying to do with it.
Thanks Ken. I am determining which bucket each order belongs to by calculating the number of days the order has been in queue. Currently I have expressionwrapper(datetime.date.today()-F(‘Date_Received’)) to get the # of days the order is in queue but the challenge is I can’t use <= in the queryset code and __lte is not working either.
You’ll want to reorganize these expressions to remove the mathematical operations so that your When expressions are based on the date_reported field.
I’d also suggest breaking this out some to make it readable.
Kinda winging this - but I think this should be close:
However, I’m getting the following in the queryset:
Order_Age
<QuerySet [{‘Aging’: ‘< 1 week’, ‘order_total’: 33}, {‘Aging’: ‘>3 weeks’, ‘order_total’: 34}]>
I checked my data, there should be 22 orders between 1-2 weeks and 12 orders between 2-3 weeks. The value of the Date_Received field is in the “##/##/####” format. Should and how would I convert that field format to match the datetime.date format?
Apologies for my novice knowledge with Django but not sure how I got the comparisons reversed. Llooking at the following two sample comparisons my understanding is that:
first one says if Date_Received is less than one_week, then i would classify this order as ‘< 1 week’
second one says if Date_Received is great than or equal to one_week and less than two_weeks, then i would classify this order as ‘1-2 weeks’.
When(Date_Received__lt=one_week, then=Value(‘< 1 week’)), When(Date_Received__gte=one_week, Date_Reported__lt=two_weeks, then=Value(‘1-2 weeks’)),
Is this not correct?
You are creating dates in the past. You are creating ranges starting from the current date and working backwards. You are making a comparison with the earliest date in the range.
For example, today (as I write this) it is 24 Feb 2025.
The one_week variable is today - 7 days → 17 Feb 2025.
For something to have happened less than a week ago, the date of the event would need to be greater than 17 Feb. Things happening between 18 Feb and 24 Feb are the events that have happened less than a week ago.
If something happened on 14 Feb, that is more than a week ago, but less than 2 weeks ago (10 Feb).
I have a follow up question related to date field in Django. I originally imported some test data (from Excel) into the backend sqlite db and i noticed the date value do not show up when I am looking at the field via the admin page. After some research, one Stack Overflow post suggested entering the date value via the admin page.
This will not be a feasible solution for me as going forward I will need to regularly import data into my Django app. Is there a more efficient way to ensure the date value from data sources are correctly loaded into the backend db?
There isn’t enough detail here for me to comment on this. I’d need to know exactly how you’re loading the data and what the data is in the spreadsheets that are causing problems.
After some research, I fixed this issue by manually enter the date via the admin page for each order entry but I’m looking for a solution which will allow the dates to show up in admin page when I import the data from csv file.