12

When I do something like

I. objects = Model.objects.all()

and then

II. objects.filter(field_1=some_condition)

I hit db every time when on the step 2 with various conditions. Is there any way to get all data in first action and then just take care of the result?

stema
  • 90,351
  • 20
  • 107
  • 135
alexvassel
  • 10,600
  • 2
  • 29
  • 31

3 Answers3

18

You actually don't hit the db until you evaluate the qs, queries are lazy.

Read more here.

edit:

After re-reading your question it becomes apparent you were asking how to prevent db hits when filtering for different conditions.

qs = SomeModel.objects.all()

qs1 = qs.filter(some_field='some_value')
qs2 = qs.filter(some_field='some_other_value')

Usually you would want the database to do the filtering for you.

You could force an evaluation of the qs by converting it to a list. This would prevent further db hits, however it would likely be worse than having your db return you results.

qs_l = list(qs)
qs1_l = [element for element in qs_l if element.some_field='some_value']
qs2_l = [element for element in qs_l if element.some_field='some_other_value']
dting
  • 38,604
  • 10
  • 95
  • 114
  • 1
    Thank's one more question. Can I hit db without converting QuerySet to a list? Or maybe I can convert list back to a QuerySet? – alexvassel May 13 '11 at 10:27
  • You can't convert list to queryset. You can hit db several ways, they are listed in the second link of DTing's answer. – DrTyrsa May 13 '11 at 10:30
  • You can hit the db by the methods mentioned in the "Read more here" link, e.g. iterating, slicing with partitions, etc. This answer http://stackoverflow.com/questions/1058135/django-convert-a-list-back-to-a-queryset/1058152#1058152 and the related question might be of interest to you. – dting May 13 '11 at 10:32
  • 5
    how to know i am hitting db with my queries? – A.J. Nov 28 '13 at 10:30
  • django_debug_toolbar will help you to identify db hits – jobima Sep 11 '19 at 06:35
2

Of course you will hit db every time. filter() transforms to SQL statement which is executed by your db, you can't filter without hitting it. So you can retrieve all the objects you need with values() or list(Model.objects.all()) and, as zeekay suggested, use Python expressions (like list comprehensions) for additional filtering.

DrTyrsa
  • 31,014
  • 7
  • 86
  • 86
  • that is not true. check the links in the answer up there: http://stackoverflow.com/a/5989752/4213969 – Vladimir Feb 27 '16 at 18:08
1

Why don't you just do objs = Model.objects.filter(field=condition)? That said, once the SQL query is executed you can use Python expressions to do further filtering/processing without incurring additional database hits.

Zach Kelling
  • 52,505
  • 13
  • 109
  • 108