refactor: replace ContentType lookup with robust filtering and validation across asset and intervention views
This commit is contained in:
parent
27056b61fa
commit
33ef94902b
17 changed files with 175 additions and 67 deletions
|
|
@ -688,10 +688,20 @@ def asset_edit_permission_required(view_func):
|
||||||
return HttpResponseForbidden(_("Missing asset information"))
|
return HttpResponseForbidden(_("Missing asset information"))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
content_type = ContentType.objects.get(model=asset_model.lower())
|
cts = ContentType.objects.filter(model=asset_model.lower())
|
||||||
model_class = content_type.model_class()
|
if not cts.exists():
|
||||||
|
return HttpResponseForbidden(_("Invalid asset type"))
|
||||||
|
cts_sorted = sorted(cts, key=lambda ct: (0 if ct.app_label == 'assets' else 1))
|
||||||
|
model_class = None
|
||||||
|
for ct in cts_sorted:
|
||||||
|
mc = ct.model_class()
|
||||||
|
if mc is not None:
|
||||||
|
model_class = mc
|
||||||
|
break
|
||||||
|
if model_class is None:
|
||||||
|
return HttpResponseForbidden(_("Invalid asset type"))
|
||||||
asset = get_object_or_404(model_class, pk=asset_id)
|
asset = get_object_or_404(model_class, pk=asset_id)
|
||||||
except ContentType.DoesNotExist:
|
except Exception:
|
||||||
return HttpResponseForbidden(_("Invalid asset type"))
|
return HttpResponseForbidden(_("Invalid asset type"))
|
||||||
|
|
||||||
if not can_edit_asset(request.user, asset):
|
if not can_edit_asset(request.user, asset):
|
||||||
|
|
|
||||||
|
|
@ -4029,6 +4029,77 @@ class ReplaceAssetStructureGeoAssetTest(TestCase):
|
||||||
self.assertEqual(new_asset.name_fr, "Asset Original")
|
self.assertEqual(new_asset.name_fr, "Asset Original")
|
||||||
|
|
||||||
|
|
||||||
|
class ExportAssetsTest(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from common.models import Thematic, UserConfig, UserThematics
|
||||||
|
from assets.models import AssetCategory, Structure, StructureLocation, StructureAssetModel, StructureGeoAsset
|
||||||
|
|
||||||
|
self.user = get_user_model().objects.create_user(
|
||||||
|
username="test_export_user",
|
||||||
|
email="export_test@example.com",
|
||||||
|
password="testpassword",
|
||||||
|
is_staff=True,
|
||||||
|
)
|
||||||
|
self.user_config = UserConfig.objects.create(user=self.user)
|
||||||
|
self.thematic = Thematic.objects.get_or_create(code="structures", defaults={"name_fr": "Structures"})[0]
|
||||||
|
UserThematics.objects.create(
|
||||||
|
user_config=self.user_config,
|
||||||
|
thematic=self.thematic,
|
||||||
|
can_view_assets=True,
|
||||||
|
can_edit_assets=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.struct = Structure.objects.create(code="EXP01", name_fr="Pont Export")
|
||||||
|
self.loc = StructureLocation.objects.create(code="EXP01A", name_fr="Loc Export", structure=self.struct)
|
||||||
|
self.category = AssetCategory.objects.create(thematic=self.thematic, code="CAT_EXP", name_fr="Cat Export")
|
||||||
|
self.model = StructureAssetModel.objects.create(code="MOD_EXP", name_fr="Mod Export", category=self.category)
|
||||||
|
self.asset = StructureGeoAsset.objects.create(
|
||||||
|
code="EXP01A-000001",
|
||||||
|
name_fr="Asset Pour Export",
|
||||||
|
structure=self.struct,
|
||||||
|
location=self.loc,
|
||||||
|
model=self.model,
|
||||||
|
category=self.category,
|
||||||
|
status="active"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_export_assets_csv_success(self):
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
self.client.force_login(self.user)
|
||||||
|
url = reverse('assets:export_assets')
|
||||||
|
ids_json = json.dumps([f"structuregeoasset:{self.asset.id}"])
|
||||||
|
|
||||||
|
response = self.client.post(url, {'ids': ids_json, 'format': 'csv'})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertEqual(response['Content-Type'], 'text/csv; charset=utf-8')
|
||||||
|
content = response.content.decode('utf-8')
|
||||||
|
self.assertIn("EXP01A-000001", content)
|
||||||
|
self.assertIn("Asset Pour Export", content)
|
||||||
|
|
||||||
|
def test_export_assets_with_duplicate_content_types(self):
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
|
# Create a second duplicate ContentType with another app_label to simulate MultipleObjectsReturned
|
||||||
|
ContentType.objects.create(
|
||||||
|
app_label='other_app',
|
||||||
|
model='structuregeoasset'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.client.force_login(self.user)
|
||||||
|
url = reverse('assets:export_assets')
|
||||||
|
ids_json = json.dumps([f"structuregeoasset:{self.asset.id}"])
|
||||||
|
|
||||||
|
# This should not raise MultipleObjectsReturned and succeed
|
||||||
|
response = self.client.post(url, {'ids': ids_json, 'format': 'csv'})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
content = response.content.decode('utf-8')
|
||||||
|
self.assertIn("EXP01A-000001", content)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -725,9 +725,13 @@ def _generate_archive_asset_code(old_asset):
|
||||||
if location and hasattr(location, 'get_direct_child_assets'):
|
if location and hasattr(location, 'get_direct_child_assets'):
|
||||||
existing_codes = set()
|
existing_codes = set()
|
||||||
assets_dict = location.get_direct_child_assets()
|
assets_dict = location.get_direct_child_assets()
|
||||||
|
if isinstance(assets_dict, dict):
|
||||||
for key, queryset in assets_dict.items():
|
for key, queryset in assets_dict.items():
|
||||||
for asset in queryset:
|
for asset in queryset:
|
||||||
existing_codes.add(asset.code)
|
existing_codes.add(asset.code)
|
||||||
|
elif hasattr(assets_dict, '__iter__'):
|
||||||
|
for asset in assets_dict:
|
||||||
|
existing_codes.add(asset.code)
|
||||||
|
|
||||||
if new_code not in existing_codes:
|
if new_code not in existing_codes:
|
||||||
return new_code
|
return new_code
|
||||||
|
|
|
||||||
|
|
@ -468,10 +468,11 @@ def clean_assets_geojson(request):
|
||||||
|
|
||||||
@check_thematic_access('clean')
|
@check_thematic_access('clean')
|
||||||
def clean_assets_detail(request, asset_model, asset_id):
|
def clean_assets_detail(request, asset_model, asset_id):
|
||||||
try:
|
content_type = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
content_type = ContentType.objects.get(model=asset_model)
|
if not content_type:
|
||||||
|
raise Http404(_("Unknown model: %(asset_model)s") % {'asset_model': asset_model})
|
||||||
model_class = content_type.model_class()
|
model_class = content_type.model_class()
|
||||||
except ContentType.DoesNotExist:
|
if not model_class:
|
||||||
raise Http404(_("Unknown model: %(asset_model)s") % {'asset_model': asset_model})
|
raise Http404(_("Unknown model: %(asset_model)s") % {'asset_model': asset_model})
|
||||||
|
|
||||||
asset = get_object_or_404(model_class, id=asset_id)
|
asset = get_object_or_404(model_class, id=asset_id)
|
||||||
|
|
|
||||||
|
|
@ -520,11 +520,11 @@ def controlcenters_locations_detail(request, location_id):
|
||||||
|
|
||||||
@check_thematic_access('controlcenters')
|
@check_thematic_access('controlcenters')
|
||||||
def controlcenters_assets_detail(request, asset_model, asset_id):
|
def controlcenters_assets_detail(request, asset_model, asset_id):
|
||||||
try:
|
content_type = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
# Récupérer le ContentType pour le modèle fourni
|
if not content_type:
|
||||||
content_type = ContentType.objects.get(model=asset_model)
|
raise Http404(_("Modèle '%(model)s' inconnu.") % {"model": asset_model})
|
||||||
model_class = content_type.model_class()
|
model_class = content_type.model_class()
|
||||||
except ContentType.DoesNotExist:
|
if not model_class:
|
||||||
raise Http404(_("Modèle '%(model)s' inconnu.") % {"model": asset_model})
|
raise Http404(_("Modèle '%(model)s' inconnu.") % {"model": asset_model})
|
||||||
|
|
||||||
# Récupérer l’objet asset
|
# Récupérer l’objet asset
|
||||||
|
|
|
||||||
|
|
@ -152,14 +152,22 @@ def export_assets(request):
|
||||||
items: list[tuple[str, object]] = []
|
items: list[tuple[str, object]] = []
|
||||||
for model_name, asset_ids in groups.items():
|
for model_name, asset_ids in groups.items():
|
||||||
try:
|
try:
|
||||||
ct = ContentType.objects.get(model=model_name)
|
cts = ContentType.objects.filter(model=model_name.lower())
|
||||||
model_class = ct.model_class()
|
if not cts.exists():
|
||||||
|
continue
|
||||||
|
cts_sorted = sorted(cts, key=lambda ct: (0 if ct.app_label == 'assets' else 1))
|
||||||
|
model_class = None
|
||||||
|
for ct in cts_sorted:
|
||||||
|
mc = ct.model_class()
|
||||||
|
if mc is not None:
|
||||||
|
model_class = mc
|
||||||
|
break
|
||||||
if model_class is None:
|
if model_class is None:
|
||||||
continue
|
continue
|
||||||
for asset in model_class.objects.filter(pk__in=asset_ids):
|
for asset in model_class.objects.filter(pk__in=asset_ids):
|
||||||
if can_view_asset(request.user, asset):
|
if can_view_asset(request.user, asset):
|
||||||
items.append((model_name, asset))
|
items.append((model_name, asset))
|
||||||
except ContentType.DoesNotExist:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
timestamp = localtime(now()).strftime('%Y%m%d_%H%M%S')
|
timestamp = localtime(now()).strftime('%Y%m%d_%H%M%S')
|
||||||
|
|
|
||||||
|
|
@ -523,11 +523,11 @@ def its_locations_detail(request, location_id):
|
||||||
|
|
||||||
@check_thematic_access('its')
|
@check_thematic_access('its')
|
||||||
def its_assets_detail(request, asset_model, asset_id):
|
def its_assets_detail(request, asset_model, asset_id):
|
||||||
try:
|
content_type = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
# Récupérer le ContentType pour le modèle fourni
|
if not content_type:
|
||||||
content_type = ContentType.objects.get(model=asset_model)
|
raise Http404(f"Modèle '{asset_model}' inconnu.")
|
||||||
model_class = content_type.model_class()
|
model_class = content_type.model_class()
|
||||||
except ContentType.DoesNotExist:
|
if not model_class:
|
||||||
raise Http404(f"Modèle '{asset_model}' inconnu.")
|
raise Http404(f"Modèle '{asset_model}' inconnu.")
|
||||||
|
|
||||||
# Récupérer l’objet asset
|
# Récupérer l’objet asset
|
||||||
|
|
|
||||||
|
|
@ -215,13 +215,12 @@ def nature_assets(request):
|
||||||
|
|
||||||
@check_thematic_access('nature')
|
@check_thematic_access('nature')
|
||||||
def nature_assets_detail(request, asset_model, asset_id):
|
def nature_assets_detail(request, asset_model, asset_id):
|
||||||
|
content_type = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
try:
|
if not content_type:
|
||||||
# Récupérer le ContentType pour le modèle fourni
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
content_type = ContentType.objects.get(model=asset_model)
|
|
||||||
model_class = content_type.model_class()
|
model_class = content_type.model_class()
|
||||||
except ContentType.DoesNotExist:
|
if not model_class:
|
||||||
raise Http404(_("Modèle %(asset_model)s inconnu.") % (asset_model))
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
|
|
||||||
# Récupérer l’objet asset
|
# Récupérer l’objet asset
|
||||||
asset = get_object_or_404(model_class, id=asset_id)
|
asset = get_object_or_404(model_class, id=asset_id)
|
||||||
|
|
|
||||||
|
|
@ -257,12 +257,12 @@ def publiclighting_assets(request):
|
||||||
|
|
||||||
@check_thematic_access('publiclighting')
|
@check_thematic_access('publiclighting')
|
||||||
def publiclighting_assets_detail(request, asset_model, asset_id):
|
def publiclighting_assets_detail(request, asset_model, asset_id):
|
||||||
try:
|
content_type = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
# Récupérer le ContentType pour le modèle fourni (ex: 'trafficlightpole')
|
if not content_type:
|
||||||
content_type = ContentType.objects.get(model=asset_model)
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
model_class = content_type.model_class()
|
model_class = content_type.model_class()
|
||||||
except ContentType.DoesNotExist:
|
if not model_class:
|
||||||
raise Http404(_("Modèle %(asset_model)s inconnu.") % (asset_model))
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
|
|
||||||
# Récupérer l’objet asset
|
# Récupérer l’objet asset
|
||||||
asset = get_object_or_404(model_class, id=asset_id)
|
asset = get_object_or_404(model_class, id=asset_id)
|
||||||
|
|
|
||||||
|
|
@ -520,12 +520,12 @@ def roads_streets_detail(request, street_id):
|
||||||
|
|
||||||
@check_thematic_access('roads')
|
@check_thematic_access('roads')
|
||||||
def roads_assets_detail(request, asset_model, asset_id):
|
def roads_assets_detail(request, asset_model, asset_id):
|
||||||
try:
|
content_type = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
# Récupérer le ContentType pour le modèle fourni
|
if not content_type:
|
||||||
content_type = ContentType.objects.get(model=asset_model)
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
model_class = content_type.model_class()
|
model_class = content_type.model_class()
|
||||||
except ContentType.DoesNotExist:
|
if not model_class:
|
||||||
raise Http404(_("Modèle %(asset_model)s inconnu.") % (asset_model))
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
|
|
||||||
# Récupérer l’objet asset
|
# Récupérer l’objet asset
|
||||||
asset = get_object_or_404(model_class, id=asset_id)
|
asset = get_object_or_404(model_class, id=asset_id)
|
||||||
|
|
|
||||||
|
|
@ -1354,12 +1354,12 @@ def trafficlights_assets_geojson(request):
|
||||||
|
|
||||||
@check_thematic_access('trafficlights')
|
@check_thematic_access('trafficlights')
|
||||||
def trafficlights_assets_detail(request, asset_model, asset_id):
|
def trafficlights_assets_detail(request, asset_model, asset_id):
|
||||||
try:
|
content_type = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
# Récupérer le ContentType pour le modèle fourni (ex: 'trafficlightpole')
|
if not content_type:
|
||||||
content_type = ContentType.objects.get(model=asset_model)
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
model_class = content_type.model_class()
|
model_class = content_type.model_class()
|
||||||
except ContentType.DoesNotExist:
|
if not model_class:
|
||||||
raise Http404(_("Modèle %(asset_model)s inconnu.") % (asset_model))
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
|
|
||||||
# Récupérer l’objet asset
|
# Récupérer l’objet asset
|
||||||
asset = get_object_or_404(model_class, id=asset_id)
|
asset = get_object_or_404(model_class, id=asset_id)
|
||||||
|
|
|
||||||
|
|
@ -527,10 +527,11 @@ def zirw_detail(request, location_id):
|
||||||
|
|
||||||
@check_thematic_access('water')
|
@check_thematic_access('water')
|
||||||
def water_assets_detail(request, asset_model, asset_id):
|
def water_assets_detail(request, asset_model, asset_id):
|
||||||
try:
|
content_type = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
content_type = ContentType.objects.get(model=asset_model)
|
if not content_type:
|
||||||
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
model_class = content_type.model_class()
|
model_class = content_type.model_class()
|
||||||
except ContentType.DoesNotExist:
|
if not model_class:
|
||||||
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
raise Http404(_("Modèle %(asset_model)s inconnu.") % {'asset_model': asset_model})
|
||||||
|
|
||||||
asset = get_object_or_404(model_class, id=asset_id)
|
asset = get_object_or_404(model_class, id=asset_id)
|
||||||
|
|
|
||||||
|
|
@ -518,9 +518,10 @@ def _get_content_type_ids_for_user(user, *, edit_only: bool) -> list[int]:
|
||||||
model_names = _THEMATIC_MODEL_MAPPING.get(thematic_code, [])
|
model_names = _THEMATIC_MODEL_MAPPING.get(thematic_code, [])
|
||||||
for model_name in model_names:
|
for model_name in model_names:
|
||||||
try:
|
try:
|
||||||
ct = ContentType.objects.get(model=model_name)
|
ct = ContentType.objects.filter(app_label='assets', model=model_name.lower()).first() or ContentType.objects.filter(model=model_name.lower()).first()
|
||||||
|
if ct:
|
||||||
result.append(ct.id)
|
result.append(ct.id)
|
||||||
except ContentType.DoesNotExist:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not hasattr(user, '_folder_cache'):
|
if not hasattr(user, '_folder_cache'):
|
||||||
|
|
|
||||||
|
|
@ -1849,9 +1849,8 @@ def interventions_add(request, thematic_code):
|
||||||
if equip_ct and equip_id:
|
if equip_ct and equip_id:
|
||||||
asset_pairs = [(int(equip_ct), int(equip_id))]
|
asset_pairs = [(int(equip_ct), int(equip_id))]
|
||||||
elif equip_type and equip_id:
|
elif equip_type and equip_id:
|
||||||
# ATTENTION: .get(model=...) suppose unicité du model name à travers les apps
|
ct = ContentType.objects.filter(app_label='assets', model=equip_type.lower()).first() or ContentType.objects.filter(model=equip_type.lower()).first()
|
||||||
# Préfère envoyer equip_ct depuis le front si possible.
|
if ct:
|
||||||
ct = ContentType.objects.get(model=equip_type.lower())
|
|
||||||
asset_pairs = [(ct.id, int(equip_id))]
|
asset_pairs = [(ct.id, int(equip_id))]
|
||||||
|
|
||||||
first_asset_obj = None
|
first_asset_obj = None
|
||||||
|
|
@ -3446,8 +3445,8 @@ def check_asset_templates_for_intervention(request, intervention_id):
|
||||||
}, status=400)
|
}, status=400)
|
||||||
|
|
||||||
# Récupérer l'asset
|
# Récupérer l'asset
|
||||||
ct = ContentType.objects.get(model=asset_type)
|
ct = ContentType.objects.filter(app_label='assets', model=asset_type.lower()).first() or ContentType.objects.filter(model=asset_type.lower()).first()
|
||||||
model_class = ct.model_class()
|
model_class = ct.model_class() if ct else None
|
||||||
if not model_class:
|
if not model_class:
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'success': False,
|
'success': False,
|
||||||
|
|
@ -3700,8 +3699,8 @@ def create_operations_from_selected_template(request, intervention_id):
|
||||||
}, status=400)
|
}, status=400)
|
||||||
|
|
||||||
# Récupérer l'asset
|
# Récupérer l'asset
|
||||||
ct = ContentType.objects.get(model=asset_type)
|
ct = ContentType.objects.filter(app_label='assets', model=asset_type.lower()).first() or ContentType.objects.filter(model=asset_type.lower()).first()
|
||||||
model_class = ct.model_class()
|
model_class = ct.model_class() if ct else None
|
||||||
if not model_class:
|
if not model_class:
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'success': False,
|
'success': False,
|
||||||
|
|
|
||||||
|
|
@ -1282,8 +1282,12 @@ def ajax_get_replacement_models_by_category(request):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Get the asset ContentType
|
# Get the asset ContentType
|
||||||
ct = ContentType.objects.get(model=asset_model)
|
ct = ContentType.objects.filter(app_label='assets', model=asset_model.lower()).first() or ContentType.objects.filter(model=asset_model.lower()).first()
|
||||||
|
if not ct:
|
||||||
|
return JsonResponse({'error': f"Unknown model: {asset_model}"}, status=400)
|
||||||
model_class = ct.model_class()
|
model_class = ct.model_class()
|
||||||
|
if not model_class:
|
||||||
|
return JsonResponse({'error': f"Unknown model: {asset_model}"}, status=400)
|
||||||
|
|
||||||
# Get the asset instance
|
# Get the asset instance
|
||||||
asset_obj = model_class.objects.get(pk=asset_id)
|
asset_obj = model_class.objects.get(pk=asset_id)
|
||||||
|
|
|
||||||
|
|
@ -3163,8 +3163,12 @@ def batch_fetch_assets_with_locations(selected_assets_array):
|
||||||
|
|
||||||
models_map = {}
|
models_map = {}
|
||||||
for model_name, ids in by_model.items():
|
for model_name, ids in by_model.items():
|
||||||
ct = ContentType.objects.get(model=model_name)
|
ct = ContentType.objects.filter(app_label='assets', model=model_name.lower()).first() or ContentType.objects.filter(model=model_name.lower()).first()
|
||||||
|
if not ct:
|
||||||
|
continue
|
||||||
Model = ct.model_class()
|
Model = ct.model_class()
|
||||||
|
if not Model:
|
||||||
|
continue
|
||||||
|
|
||||||
# détecter quelles FKs de localisation existent réellement sur le modèle
|
# détecter quelles FKs de localisation existent réellement sur le modèle
|
||||||
related_fields = []
|
related_fields = []
|
||||||
|
|
|
||||||
|
|
@ -555,7 +555,9 @@ def intervention_add_preventive(request, thematic_code):
|
||||||
asset_id = a['id']
|
asset_id = a['id']
|
||||||
|
|
||||||
# ContentType de l'asset
|
# ContentType de l'asset
|
||||||
ct_asset = ContentType.objects.get(model=model_name)
|
ct_asset = ContentType.objects.filter(app_label='assets', model=model_name.lower()).first() or ContentType.objects.filter(model=model_name.lower()).first()
|
||||||
|
if not ct_asset:
|
||||||
|
continue
|
||||||
|
|
||||||
# Objet asset préchargé (avec ses FKs)
|
# Objet asset préchargé (avec ses FKs)
|
||||||
asset_obj = assets_map.get(model_name, {}).get(asset_id)
|
asset_obj = assets_map.get(model_name, {}).get(asset_id)
|
||||||
|
|
@ -671,7 +673,9 @@ def intervention_add_preventive(request, thematic_code):
|
||||||
for a in selected_assets_array:
|
for a in selected_assets_array:
|
||||||
model_name = a['asset_type']
|
model_name = a['asset_type']
|
||||||
asset_id = a['id']
|
asset_id = a['id']
|
||||||
ct_asset = ContentType.objects.get(model=model_name)
|
ct_asset = ContentType.objects.filter(app_label='assets', model=model_name.lower()).first() or ContentType.objects.filter(model=model_name.lower()).first()
|
||||||
|
if not ct_asset:
|
||||||
|
continue
|
||||||
|
|
||||||
InterventionAsset.objects.get_or_create(
|
InterventionAsset.objects.get_or_create(
|
||||||
intervention=intervention,
|
intervention=intervention,
|
||||||
|
|
@ -783,7 +787,9 @@ def intervention_add_preventive(request, thematic_code):
|
||||||
for a in selected_assets_array:
|
for a in selected_assets_array:
|
||||||
model_name = a['asset_type']
|
model_name = a['asset_type']
|
||||||
asset_id = a['id']
|
asset_id = a['id']
|
||||||
ct_asset = ContentType.objects.get(model=model_name)
|
ct_asset = ContentType.objects.filter(app_label='assets', model=model_name.lower()).first() or ContentType.objects.filter(model=model_name.lower()).first()
|
||||||
|
if not ct_asset:
|
||||||
|
continue
|
||||||
asset_obj = assets_map.get(model_name, {}).get(asset_id)
|
asset_obj = assets_map.get(model_name, {}).get(asset_id)
|
||||||
|
|
||||||
# Filtrer les templates applicables à cet asset
|
# Filtrer les templates applicables à cet asset
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue