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' 父级的表单以便能够:
- 用 GET
发送的值设置初始 pro_ide 值
- 隐藏此 pro_ide 字段
- 自定义 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')
我已经将(参见下面的 link)发布到 'valid' 我的 ER 图。
我尝试开发一个基于 'trought' 模型的表单,带有嵌套的内联表单集。
当我在 UtilisateurCreateView 中定义字段时它起作用 class 但我想自定义 'trought' 父级的表单以便能够:
- 用 GET 发送的值设置初始 pro_ide 值
- 隐藏此 pro_ide 字段
- 自定义 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')