Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding values to Django QuerySet

Is there any way to append a non-Django supplied value to a query?

For instance, to find out if a store closed, I may run a function called get_closed_stores() which returns a list of closed stores.

Stores Closed

[00090, 00240, 00306, 00438, 03005, 05524]

Great, now we have store numbers for stores that are closed. Lets get those actual store objects.

Query

Store.objects.filter(
store_number__in=[00090, 00240, 00306, 00438, 03005, 05524]
)

We now have the QuerySet, but we have absolutely no way to detect when the store closed, because the database doesn't contain any information about emergency closings, but Sharepoint does. So back at get_closed_stores() we can return the Date Closed alongside the store number so our Closed Stores List (dictionary) would look more like below:

Store List with Dates

{
    [00090, '1/28/19 5:00PM'], 
    [00240,'1/28/19 5:00PM'], 
    [00306, '1/28/19 5:00PM'], 
    [00438,'1/28/19 5:00PM'], 
    [03005,'1/28/19 5:00PM'], 
    [05524, '1/28/19 5:00PM']
}

Now that the dates are with my store numbers, I can add this to my Queryset (ideally) and access it from my front end.

So annotate() would be ideal here if I were working with anything Django ORM related, but when it comes to "injecting" external data, what is it I'm looking for?

I can absolutely just make the call for each store from JS on my front end but I would rather not if I can get around it

like image 289
CodeSpent Avatar asked Mar 05 '23 15:03

CodeSpent


1 Answers

A QuerySet in itself isn't anything magical or special, in the end its still a dictionary, so I had the random notion to append to the dictionary the way I typically would, and it worked.

My function is now returning a dictionary:

{ "store_number": "close_date" }

My view takes this dictionary and uses the keys (store numbers) to Query the database and then appends the store's close date as store.close_date by simply saying:

store.close_date = store_list[store_number]

This is likely to change, but I want to keep it close to the original question to make it readable for future readers. Below is my view.

@login_required
def store_closures(request):
    store_list = get_closed_stores()
    store_nums = store_list.keys()
    closed_stores = Store.objects.filter(store_number__in=store_nums)
    for store in closed_stores:
        store.close_date = store_list["{:05d}".format(store.store_number)]
    return render(request, 'all_store_closures.html', {'closed_stores':closed_stores})

So if you want to add a non Django value to a queryset, you can just use the standard method of appending to a dictionary.

for obj in query:
    obj.desired_name = 'desired_value'

Which is, of course, accessed using {{ object.desired_name }} from your template.

like image 69
CodeSpent Avatar answered Mar 14 '23 23:03

CodeSpent