Bonjour,

J'utilise des formulaires nichés (inlineformset) et le schéma relationnel ci-dessous :


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
Projet 1---* ProjetUtilisateur *---1 Utilisateur
                 1
                 |
                 *
             Application
J'ai un formulaire 'Update' Application sur lequel le champ Projet est caché et le champ Utilisateur en lecture seule.

Mon problème vient de ce champ Utilisateur que je n'arrive pas à afficher comme je veux à savoir :
- type input (widget)
- readonly
- affiche une concaténation de champs de la table utilisateur (et non pas la clé primaire de l'objet)

Pourtant la méthode to_string est bien la concaténation que je souhaite afficher pour un objet Utilisateur.

Actuellement, j'ai conservé un select (widget) et je ne passe que l'utilisateur concernée en readonly mais je ne trouve pas çà très propre (lignes commentées dans forms.py).

Il y a bien l'option to_field_name mais je ne peux utiliser qu'un champ et non pas une concaténation.

De ce que j'ai pu lire, la solution pourrait être d'écrire une classe personnalisée ModelChoiceField héritant de ModelChoiceField dans laquelle je surcharge la méthode label_from_instance pour afficher un champ texte.

Mais cela ne fonctionne pas et c'est toujours la PK qui est affichée.

D'avance merci pour votre aide

models.py
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
class Utilisateur(SafeDeleteModel):
 
    _safedelete_policy = SOFT_DELETE_CASCADE
    uti_ide = models.AutoField(primary_key = True)
    projets = models.ManyToManyField(Projet, through='UtilisateurProjet')
    uti_nom = models.CharField("Nom", max_length=20)
    uti_pre = models.CharField("Prénom", max_length=20)
    uti_mai = models.CharField("Email", max_length=40)
    uti_sit = models.CharField("Equipe", max_length=20, null=True, blank=True)
    uti_pro = models.CharField("Fonction/profil", max_length=200, null=True, blank=True)
    uti_log = models.CharField("Log utilisateur", max_length=20, null=True, blank=True)
    uti_dat = models.DateTimeField("Date log",auto_now_add=True, null=True, blank=True)
    log = HistoricalRecords()
 
    @classmethod
    def options_list(cls,pro_ide):
 
        utilisateurs = Utilisateur.objects.filter(projets__pro_ide=pro_ide)
        the_opts_list = [(utilisateur.uti_ide, utilisateur.uti_nom+', '+utilisateur.uti_pre) for utilisateur in utilisateurs]
        the_opts_list.insert(0, (None, ''))
        return the_opts_list
 
    class Meta:
 
        db_table = 'tbl_uti'
        verbose_name_plural = 'Utilisateurs'
        ordering = ['uti_ide']
 
    def __str__(self):
 
        return f"{self.uti_nom}, {self.uti_pre} ({self.uti_mai})"

forms.py
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
 
class UtilisateurModelChoiceField(ModelChoiceField):
 
    def label_from_instance(self, obj):
        return obj.uti_nom+', '+obj.uti_pre+' ('+obj.uti_mai+')'
 
 
class UtilisateurModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        print('label')
        return obj.uti_nom+', '+obj.uti_pre+' ('+obj.uti_mai+')'
 
 
class UtilisateurProjetUpdateForm(forms.ModelForm):
 
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop("request") 
        super(UtilisateurProjetUpdateForm, self).__init__(*args, **kwargs)
        # print('kwargs',self.request)
        # print('projet',self.request['projet'])
        # print('utilisateur',self.request['utilisateur'])
 
        PROJETS = Projet.objects.all()
        UTILISATEURS = Utilisateur.objects.all()
        self.fields["pro_ide"] = forms.ModelChoiceField(queryset = PROJETS, label = "Nom projet", widget = forms.HiddenInput(), initial = Projet.objects.get(pro_ide=self.request['projet']))
        self.fields["uti_ide"] = UtilisateurModelChoiceField(queryset = UTILISATEURS, label = "Nom, prénom de l'utilisateur", widget = forms.TextInput(attrs={'readonly':'readonly'}), initial = Utilisateur.objects.get(uti_ide=self.request['utilisateur']),) #,to_field_name="uti_nom"
 
        # UTILISATEURS = Utilisateur.objects.filter(uti_ide = self.request['utilisateur'])
        # self.fields["uti_ide"] = UtilisateurModelChoiceField(queryset = UTILISATEURS, label = "Nom, prénom de l'utilisateur", widget = forms.Select(attrs={'readonly':'readonly'}), initial = Utilisateur.objects.get(uti_ide=self.request['utilisateur']),) #,to_field_name="uti_nom"
 
 
    class Meta:
        model = UtilisateurProjet
        fields = ('pro_ide','uti_ide',)