[Fixed]-Django: filter a RawQuerySet

23👍

.raw() is an end-point. Django can’t do anything with the queryset because that would require being able to somehow parse your SQL back into the DBAPI it uses to create SQL in the first place. If you use .raw() it is entirely on you to construct the exact SQL you need.

If you can somehow reduce your query into something that could be handled by .extra() instead. You could construct whatever query you like with Django’s API and then tack on the additional SQL with .extra(), but that’s going to be your only way around.

2👍

There’s another option: turn the RawQuerySet into a list, then you can do your sorting like this…

results_list.sort(key=lambda item:item.some_numeric_field, reverse=True)

and your filtering like this…

filtered_results = [i for i in results_list if i.some_field == 'something'])

…all programatically. I’ve been doing this a ton to minimize db requests. Works great!

2👍

I implemented Django raw queryset which supports filter(), order_by(), values() and values_list(). It will not work for any RAW query but for typical SELECT with some INNER JOIN or a LEFT JOIN it should work.

The FilteredRawQuerySet is implemented as a combination of Django model QuerySet and RawQuerySet, where the base (left part) of the SQL query is generated via RawQuerySet, while WHERE and ORDER BY directives are generared by QuerySet:

https://github.com/Dmitri-Sintsov/django-jinja-knockout/blob/master/django_jinja_knockout/query.py

It works with Django 1.8 .. 1.11.

It also has a ListQuerySet implementation for Prefetch object result lists of model instances as well, so these can be processed the same way as ordinary querysets.

Here is the example of usage:

https://github.com/Dmitri-Sintsov/djk-sample/search?l=Python&q=filteredrawqueryset&type=&utf8=%E2%9C%93

0👍

Another thing you can do is that if you are unable to convert it to a regular QuerySet is to create a View in your database backend. It basically executes the query in the View when you access it. In Django, you would then create an unmanaged model to attach to the View. With that model, you can apply filter as if it were a regular model. With your foreign keys, you would set the on_delete arg to models.DO_NOTHING.

More information about unmanaged models:
https://docs.djangoproject.com/en/2.0/ref/models/options/#managed

👤Bobort

Leave a comment