Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django inline formsets and choicefields generate too many db queries

I have a model with a number of foreign key fields, e.g. model Product with fields 'type', 'level', 'color', 'intensity' (just a generic example).

I then have a page to edit all products of a given type using a Type form with the products as an inline formset with the option to add additional products inline using extra=10.

The thing i find very strange is that each time when i output one of the foreign key choice fields on the template Django queries the database for the get the options (every time).

For example:

{% for form in formset %}
    {{ form.level }}
    {{ form.color }}
    {{ form.intensity }}
{% endfor %}

With 20 products (and 10 empty extra forms) the above code issues 30 select * from ... from level, color and intensity totaling 90 queries (revealed using the Django Debug Toolbar), where 3 should be sufficient. The options are unlikely to change mid request, but even if they did I definitely wouldn't want some newly added options to appear in the last 5 forms only.

Is there any way to optimize my models/forms/views/templates so that the database doesn't get hammered like this unnecessarily?

-

Disclaimer: I'm relatively new to django and python and can't help thinking there must be a way to address this built in somehow.

like image 709
davur Avatar asked Mar 06 '12 11:03

davur


2 Answers

field_queryset = Test.objects.all()    
for form in formset:
        form.fields['test_field'].queryset = field_queryset

Like this.

like image 119
Denis Kataev Avatar answered Nov 10 '22 00:11

Denis Kataev


You can change the queryset used by the formset, then you could use select_related() to generate the FK joins rather than to execute a query at each forloop iteration.

like image 26
jpic Avatar answered Nov 10 '22 00:11

jpic