#30455 closed Cleanup/optimization (invalid)
Django ModelForm with multiple ForeignKey query optimisation issue.
Reported by: | Bishnu Bhattarai | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In django ModelForm, I have two foreignkey fields 'account' and reference,
self.fieldsaccount.queryset = Account.objects.all()
self.fieldsreference.queryset = Billing.objects.all()
I have 2000 rows in Account table and 4000 rows in Billing table.
While rendering this form, server responded with 504 status.
I thought, while rendering this form, these two queryset are executed at once and sets the options in choice filed. But I found the queryset are executed in loop and response server error 504. This is because database is hit for every choices of foreignkey and db-query is executed in loop.
Hoping the issue will be resolved soon.
Change History (7)
comment:1 by , 6 years ago
Component: | Forms → Database layer (models, ORM) |
---|---|
Resolution: | → invalid |
Status: | new → closed |
Version: | 2.1 → master |
comment:2 by , 6 years ago
Resolution: | invalid |
---|---|
Status: | closed → new |
We cannot use select_related for two unrelated querysets in django form. Can you please give me some example. The solution you have provided is not what I mean. Please test django-model form with two foreignkey fields in forms and with rows that I have mentioned above it will not response as fast as we need takes more than 40-50 sec and gets timeout.
comment:3 by , 6 years ago
Sorry I missed that you're talking about ModelForm. If you have form with two fields (e.g. ModelChoiceField
) then queryset for each field will be executed once, I don't understand what loop do you mean. Can you provide example project?
comment:4 by , 6 years ago
class BillingForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(BillingForm, self).__init__(*args, **kwargs) self.fields['account'].queryset = Account.objects.all() self.fields['refrence'].queryset = Billing.objects.all() class Meta: model = Billing fields = ('account', 'refrence', 'amount', 'remarks', ) views.py class BillingUpdateView(SuccessMessageMixin, UpdateView): template_name = 'billing/billing-form.html' model = Billing form_class = BillingForm success_url = reverse_lazy('billing_report') success_message = 'Billing Updated Successfully.' @method_decorator(staff_required()) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs)
I have 2000 rows in Account table and 4-5K rows in Billing table. Try to render the above example form with number of rows that I have mentioned and see the response time. You can use model_mummy for generate dummy data.
comment:5 by , 6 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I don't see any issue here you have two querysets so two queries, nothing unusual. Maybe your Account
, Billing
models are complicated, it's hard to tell without an entire project. It is normal that if you want to render a long list it will take time, I'm not sure what do you expect from Django and where we could be smarter 🤷.
Please use one of support channels.
comment:6 by , 6 years ago
Please have a look at this issue, Have you tried with my views and number of rows. If just 5 thousands rows in a table responding 504 status or taking more than one minute, then how it is useful ? Please immitate my situation with number of rows in mysql db, you will certainly get noticed what's wrong. I have got noticed this issue after debugging it for two days.
comment:7 by , 6 years ago
5000 rows in each of foreign keys works perfectly for me, ~1sec. for render. Trac is not a place for debugging code. Again, please use one of support channels, I'm sure that you will find help on e.g. #django IRC channel.
You can use select_related() to prevent multiple queries.
Closing per TicketClosingReasons/UseSupportChannels.