perf(contracts): optimize ContractAdmin queries on add and change views
- Avoid loading all database ContractPost instances when adding a new contract
- Use select_related('contract') on ContractPost to prevent N+1 queries in __str__
- Only include ContractOperationTemplatePostInline on saved contracts
- Add prefetch_related('teams') for CompanyMember in pause reason assignments
- Optimize ContractAdmin changelist queryset with select_related and prefetch_related
This commit is contained in:
parent
6782959253
commit
41679d82e9
1 changed files with 20 additions and 3 deletions
|
|
@ -75,6 +75,11 @@ def _get_pause_reason_inline():
|
||||||
verbose_name = "Réassignation automatique sur pause"
|
verbose_name = "Réassignation automatique sur pause"
|
||||||
verbose_name_plural = "Réassignations automatiques sur pause"
|
verbose_name_plural = "Réassignations automatiques sur pause"
|
||||||
|
|
||||||
|
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
||||||
|
if db_field.name == "assigned_member":
|
||||||
|
kwargs["queryset"] = CompanyMember.objects.prefetch_related('teams').order_by('name')
|
||||||
|
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
||||||
|
|
||||||
return ContractPauseReasonAssignmentInline
|
return ContractPauseReasonAssignmentInline
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -106,15 +111,21 @@ def _get_operation_template_posts_inline():
|
||||||
if db_field.name == "contract_post":
|
if db_field.name == "contract_post":
|
||||||
contract_id = request.resolver_match.kwargs.get('object_id') if request.resolver_match else None
|
contract_id = request.resolver_match.kwargs.get('object_id') if request.resolver_match else None
|
||||||
if contract_id:
|
if contract_id:
|
||||||
kwargs["queryset"] = ContractPost.objects.filter(contract_id=contract_id).order_by('order_number')
|
kwargs["queryset"] = ContractPost.objects.filter(
|
||||||
|
contract_id=contract_id
|
||||||
|
).select_related('contract').order_by('order_number')
|
||||||
|
else:
|
||||||
|
kwargs["queryset"] = ContractPost.objects.none()
|
||||||
elif db_field.name == "operation_template":
|
elif db_field.name == "operation_template":
|
||||||
contract_id = request.resolver_match.kwargs.get('object_id') if request.resolver_match else None
|
contract_id = request.resolver_match.kwargs.get('object_id') if request.resolver_match else None
|
||||||
if contract_id:
|
if contract_id:
|
||||||
contract = Contract.objects.filter(pk=contract_id).first()
|
contract = Contract.objects.prefetch_related('thematics').filter(pk=contract_id).first()
|
||||||
if contract and contract.thematics.exists():
|
if contract and contract.thematics.exists():
|
||||||
kwargs["queryset"] = OperationTemplate.objects.filter(
|
kwargs["queryset"] = OperationTemplate.objects.filter(
|
||||||
Q(thematic__in=contract.thematics.all()) | Q(thematic__isnull=True)
|
Q(thematic__in=contract.thematics.all()) | Q(thematic__isnull=True)
|
||||||
).distinct().order_by('name')
|
).distinct().order_by('name')
|
||||||
|
else:
|
||||||
|
kwargs["queryset"] = OperationTemplate.objects.none()
|
||||||
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
return super().formfield_for_foreignkey(db_field, request, **kwargs)
|
||||||
|
|
||||||
return ContractOperationTemplatePostInline
|
return ContractOperationTemplatePostInline
|
||||||
|
|
@ -131,8 +142,14 @@ class ContractAdmin(admin.ModelAdmin):
|
||||||
list_filter = ('is_blocked', 'is_active', 'municipalities', 'thematics', 'uses_occupations', 'occupations_required', 'uses_intervention_manager', 'allow_team_members_edit', 'auto_assign_control_team', 'send_daily_summary')
|
list_filter = ('is_blocked', 'is_active', 'municipalities', 'thematics', 'uses_occupations', 'occupations_required', 'uses_intervention_manager', 'allow_team_members_edit', 'auto_assign_control_team', 'send_daily_summary')
|
||||||
filter_horizontal = ('thematics', 'municipalities')
|
filter_horizontal = ('thematics', 'municipalities')
|
||||||
|
|
||||||
|
def get_queryset(self, request):
|
||||||
|
return super().get_queryset(request).select_related('company', 'executive_officer').prefetch_related('municipalities', 'thematics')
|
||||||
|
|
||||||
def get_inlines(self, request, obj=None):
|
def get_inlines(self, request, obj=None):
|
||||||
return [_get_pause_reason_inline(), _get_symptom_autoclose_inline(), _get_operation_template_posts_inline()] + list(super().get_inlines(request, obj))
|
inlines = [_get_pause_reason_inline(), _get_symptom_autoclose_inline()]
|
||||||
|
if obj:
|
||||||
|
inlines.append(_get_operation_template_posts_inline())
|
||||||
|
return inlines + list(super().get_inlines(request, obj))
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {
|
(None, {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue