def _parse_field_rows(form): field_names = form.getlist("field_name[]") field_types = form.getlist("field_type[]") field_relations = form.getlist("field_relation[]") field_required = form.getlist("field_required[]") field_min = form.getlist("field_min[]") field_max = form.getlist("field_max[]") fields = [] for i, fname in enumerate(field_names): if not fname.strip(): continue ftype = field_types[i] relation_definition_id = field_relations[i] if i < len(field_relations) else None if ftype == "relation" and not (relation_definition_id or "").strip().isdigit(): # Type "Relation vers un autre objet" choisi sans (ou avant # d'avoir pu) sélectionner d'objet cible réel — ex. le tout # premier objet créé dans un jeu, quand ce sélecteur est encore # vide faute d'un autre objet à pointer. create_definition() # fait un int(relation_definition_id) sans filet : le laisser # passer plantait TOUTE la requête (500), et comme la ligne # _definitions n'était alors jamais validée (pas de commit() # atteint), l'objet n'était pas créé du tout — pas de champ # "Relation" non plus, mais un panneau qui semble "ne rien # faire" plutôt qu'un message d'erreur clair. On ignore donc ce # champ précis (comme une ligne sans nom, ci-dessus) plutôt que # de faire échouer la création de TOUT l'objet à cause de lui. continue fields.append({ "name": fname.strip(), "type": ftype, "relation_definition_id": relation_definition_id, "required": field_required[i] == "1" if i < len(field_required) else False, "min_value": (field_min[i].strip() or None) if i < len(field_min) else None, "max_value": (field_max[i].strip() or None) if i < len(field_max) else None, }) return fields