refactor: optimize admin queries and add dependent dropdown logic for contract posts in operation templates

This commit is contained in:
kdeterme 2026-08-19 16:28:51 +02:00
parent 0d35e71cfc
commit 28f8204f5a

View file

@ -713,25 +713,21 @@ class OperationTemplateAdminForm(forms.ModelForm):
ct = ContentType.objects.get_for_model(model)
# Filter instances by categories first (most specific), then by thematic
qs = model.objects.select_related('category')
if category_ids:
instances = model.objects.filter(
category_id__in=category_ids
).order_by('code')
instances = qs.filter(category_id__in=category_ids).order_by('code')
elif thematic_id:
instances = model.objects.filter(
category__thematic_id=thematic_id
).order_by('code')
instances = qs.filter(category__thematic_id=thematic_id).order_by('code')
else:
instances = model.objects.all().order_by('code')
instances = qs.all().order_by('code')
if instances.exists():
for instance in instances:
# Value format: "content_type_id:object_id"
value = f"{ct.id}:{instance.pk}"
# Display with category info
category_name = instance.category.get_name() if instance.category else ''
display = f"{instance} ({category_name})" if category_name else str(instance)
choices.append((value, display))
for instance in instances:
# Value format: "content_type_id:object_id"
value = f"{ct.id}:{instance.pk}"
# Display with category info
category_name = instance.category.get_name() if instance.category else ''
display = f"{instance} ({category_name})" if category_name else str(instance)
choices.append((value, display))
except (TypeError, Exception):
continue
@ -778,8 +774,33 @@ class OperationTemplateAdminForm(forms.ModelForm):
js = ('interventions/admin_operation_template_dynamic.js',)
class ContractOperationTemplatePostInlineForm(forms.ModelForm):
class Meta:
model = ContractOperationTemplatePost
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
from contracts.models import ContractPost
contract_id = None
if self.instance and self.instance.pk and self.instance.contract_id:
contract_id = self.instance.contract_id
elif self.data:
prefix = self.prefix
contract_key = f"{prefix}-contract" if prefix else "contract"
contract_id = self.data.get(contract_key)
if contract_id:
self.fields['contract_post'].queryset = ContractPost.objects.filter(
contract_id=contract_id
).order_by('order_number')
else:
self.fields['contract_post'].queryset = ContractPost.objects.none()
class OperationTemplateContractPostInline(admin.TabularInline):
model = ContractOperationTemplatePost
form = ContractOperationTemplatePostInlineForm
extra = 0
fields = ('contract', 'contract_post', 'default_quantity', 'comment')
verbose_name = "Poste de contrat par défaut"
@ -794,6 +815,10 @@ class OperationTemplateContractPostInline(admin.TabularInline):
kwargs["queryset"] = Contract.objects.filter(
thematics=template.thematic
).distinct().select_related('company').order_by('contract_number')
else:
kwargs["queryset"] = Contract.objects.all().select_related('company').order_by('contract_number')
else:
kwargs["queryset"] = Contract.objects.all().select_related('company').order_by('contract_number')
return super().formfield_for_foreignkey(db_field, request, **kwargs)
@ -818,6 +843,13 @@ class OperationTemplateAdmin(admin.ModelAdmin):
'description': 'Sélectionnez les modèles d\'équipements spécifiques. Si vide, tous les modèles des catégories sélectionnées seront concernés.',
}),
)
def get_queryset(self, request):
return super().get_queryset(request).select_related(
'thematic', 'team', 'team__company'
).prefetch_related(
'categories', 'asset_model_filters'
)
@admin.display(description='Catégories')
def categories_list(self, obj):
@ -834,8 +866,31 @@ class OperationTemplateAdmin(admin.ModelAdmin):
return ', '.join(str(f) for f in filters) + ('...' if obj.asset_model_filters.count() > 3 else '')
class ContractOperationTemplatePostAdminForm(forms.ModelForm):
class Meta:
model = ContractOperationTemplatePost
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
from contracts.models import ContractPost
contract_id = None
if self.instance and self.instance.pk and self.instance.contract_id:
contract_id = self.instance.contract_id
elif self.data and 'contract' in self.data:
contract_id = self.data.get('contract')
if contract_id:
self.fields['contract_post'].queryset = ContractPost.objects.filter(
contract_id=contract_id
).order_by('order_number')
else:
self.fields['contract_post'].queryset = ContractPost.objects.none()
@admin.register(ContractOperationTemplatePost)
class ContractOperationTemplatePostAdmin(admin.ModelAdmin):
form = ContractOperationTemplatePostAdminForm
list_display = ('contract', 'operation_template', 'contract_post', 'default_quantity', 'comment')
list_filter = ('contract', 'operation_template', 'contract__thematics')
search_fields = (
@ -850,6 +905,11 @@ class ContractOperationTemplatePostAdmin(admin.ModelAdmin):
class Media:
js = ('interventions/admin_operation_template_dynamic.js',)
def get_queryset(self, request):
return super().get_queryset(request).select_related(
'contract', 'contract__company', 'operation_template', 'contract_post'
)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "contract_post":
obj_id = request.resolver_match.kwargs.get('object_id') if request.resolver_match else None