Django:如何在基于 class 的视图中定义表单? -> 错误无法分配 '..' '..' 必须是 "Utilisateur" 实例

Django: how to define form in class based views? -> error Cannot assign '..' '..' must be a "Utilisateur" instance

我已经将(参见下面的 link)发布到 'valid' 我的 ER 图。

我尝试开发一个基于 'trought' 模型的表单,带有嵌套的内联表单集。

当我在 UtilisateurCreateView 中定义字段时它起作用 class 但我想自定义 'trought' 父级的表单以便能够:

  1. 用 GET
  2. 发送的值设置初始 pro_ide 值
  3. 隐藏此 pro_ide 字段
  4. 自定义 uti_ide 字段标签

所以我定义了一个基于 'throught' 模型的 UtilisateurProjetCreateForm,就像我以前做的那样,但是我得到了一个错误:

Cannot assign "'Slater, Kelly (k.slater@surf.com)'": "UtilisateurProjet.uti_ide" must be a "Utilisateur" instance.

此外,由于此表格基于 'throught' 模型,我不确定是否应该定义 forms.ChoiceField...

models.py

class Projet(SafeDeleteModel):

    _safedelete_policy = SOFT_DELETE_CASCADE
    pro_ide = models.AutoField(primary_key = True)
    # utilisateurs = models.ManyToManyField(Utilisateur, through='UtilisateurProjet')
    pro_nom = models.IntegerField("Nom du projet")
    pro_log = models.CharField("Log utiisateur", max_length=20, null=True, blank=True)
    pro_dat = models.DateTimeField("Date log",auto_now_add=True)
    pro_act = models.IntegerField("Projet en cours ?", null=True, blank=True)

    class Meta:

        db_table = 'tbl_pro'
        verbose_name_plural = 'Projets'
        ordering = ['pro_ide']
        permissions = [
            ('can_add_project','Can add project'),
        ]

    def __str__(self):

        return f"{self.pro_nom}"

class Utilisateur(SafeDeleteModel):

    _safedelete_policy = SOFT_DELETE_CASCADE
    uti_ide = models.AutoField(primary_key = True)
    # pro_ide = models.ForeignKey(Projet, on_delete = models.CASCADE) # related project
    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_dem_dat = models.DateTimeField("Date demande",auto_now_add=True, null=True, blank=True)
    uti_val = models.IntegerField("Demande validée ?", null=True, blank=True)
    uti_val_dat = models.DateTimeField("Date validation",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)

    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})"

class UtilisateurProjet(models.Model):

    _safedelete_policy = SOFT_DELETE_CASCADE
    pro_uti_ide = models.AutoField(primary_key = True)
    uti_ide = models.ForeignKey(Utilisateur, on_delete=models.CASCADE)
    pro_ide = models.ForeignKey(Projet, on_delete=models.CASCADE)

    class Meta:

        db_table = 'tbl_pro_uti'

class Application(SafeDeleteModel):

    _safedelete_policy = SOFT_DELETE_CASCADE
    app_ide = models.AutoField(primary_key = True)
    # uti_ide = models.ForeignKey(Utilisateur, on_delete = models.CASCADE) # related utilisateur
    pro_uti_ide = models.ForeignKey(UtilisateurProjet, on_delete = models.CASCADE) # related utilisateur-projet
    app_app_nom = models.IntegerField("Nom application", null=True, blank=True)
    app_dro = models.IntegerField("Droit sur application", null=True, blank=True)
    app_sta = models.IntegerField("Statut (création/Modification/Suppression", null=True, blank=True)
    app_log = models.CharField("Log utilisateur", max_length=20, null=True, blank=True)
    app_dat = models.DateTimeField("Date log",auto_now_add=True, null=True, blank=True)

    class Meta:

        db_table = 'tbl_app'
        verbose_name_plural = 'Applications'
        ordering = ['app_ide']

views.py

# 
class UtilisateurCreateView(FormView):
    template_name = 'project/utilisateurprojet_form.html'
    form_class = UtilisateurProjetCreateForm

    def get_context_data(self, **kwargs):
        data = super().get_context_data(**kwargs)
        if self.request.POST:
            data["utilisateur"] = self.request.user.username # nom de l'utilisateur connecté
            data["projet"] = get_object_or_404(Projet, pro_ide = self.request.GET['projet'])
            data["application"] = ApplicationFormset(self.request.POST)
        else:
            data["application"] = ApplicationFormset()
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        application = context["application"]
        self.object = form.save(commit=False)
        self.object.uti_log = context["utilisateur"]
        self.object.save()

        if application.is_valid():
            application.instance = self.object
            application.save()
        return super().form_valid(form)

    def get_success_url(self):
        return reverse("project:index")

forms.py

ApplicationFormset = inlineformset_factory(
    UtilisateurProjet, Application, 
    fields=('app_app_nom','app_dro'),
    widgets={
        'app_app_nom': forms.Select(choices=NAME),
        'app_dro': forms.Select(choices=ACCESS)
    },
    extra=3,
    can_delete=True,
)

class UtilisateurProjetCreateForm(forms.ModelForm):

    PROJETS = [(Projet.objects.get(pro_ide=1),'Coverage Africa'),]
    UTILISATEURS = [(Utilisateur.objects.get(uti_ide=1),'Slater'),]
    pro_ide = forms.ChoiceField(label = "Nom projet", widget = forms.Select, choices = PROJETS, initial = Projet.objects.get(pro_ide=1), disabled=True)
    uti_ide = forms.ChoiceField(label = "Nom, prénom de l'utilisateur", widget = forms.Select, choices = UTILISATEURS)

    class Meta:
        model = UtilisateurProjet
        fields = ('pro_ide','uti_ide')

我必须在我的 ModelForm 中使用 ModelChoiceFiled:

class UtilisateurProjetCreateForm(forms.ModelForm):

    PROJETS = Projet.objects.all()
    UTILISATEURS = Utilisateur.objects.all()
    pro_ide = forms.ModelChoiceField(queryset = PROJETS, label = "Nom projet", widget = forms.Select, initial = Projet.objects.get(pro_ide=1))
    uti_ide = forms.ModelChoiceField(queryset = UTILISATEURS, label = "Nom, prénom de l'utilisateur", widget = forms.Select)

    class Meta:
        model = UtilisateurProjet
        fields = ('pro_ide','uti_ide')