Django Q object - Is it possible to put those two queries together even if one depends from another?

30 Views Asked by At

Does anyone knows if is possible to put together two Q object queries in only one.

Is the first time I need to use it and I am quite lost.

First query:

vendors = Vendor.objects.filter(Q(is_approved=True, user__is_active=True), user_profile__location__distance_lte=(pnt, D(km=1))
   ).annotate(distance=Distance("user_profile__location", pnt)).order_by("distance")

Second query:

vendors = vendors.filter(Q(vendor_max_delivery_distance__gte=Distance("user_profile__location", pnt)))

Can i make a function like a helper so I could call it whenever needs? Is it better to do it in models or contextprocessors?

Thank you very much in advance!!!

1

There are 1 best solutions below

1
SamSparx On BEST ANSWER

In the simplest sense, Q allows you to use OR criteria in your filter (the normal, comma separated criteria are ANDs). If that's what you're after, your first line should look something like

Vendor.objects.filter(
    Q(is_approved=True) | Q(user__is_active=True),
    user_profile__location__distance_lte=(pnt, D(km=1))

In pseudocode that means

Vendor where (EITHER is_approved OR user__is_active) AND user..distance__lte(pnt, D(Km=1))

(note the double underscore after lte)

You can also filter based on annnotations, so you can extend the original query to include the second line, eg

annotate(distance=...).filter(distance__gte=...)

As the second filter doesn't need an OR statement, you don't actually need Q to process it, and it can have its own filter criteria after annotate.

On a final note, it is quite possible to set up a query in a view ahead of time and only use it when necessary (django has lazy evaluation so it wont make database calls until required to). Setting it up in a model or context processor really depends on the use case. If you are just generating data to use as context in a view, then the view is probably a good place for it.