Django模型表单提交后显示对象而非选项名称问题求助
问题:Django表单提交后Admin显示对象而非选项名称
我用Django框架开发Web应用,基于NewIncidents模型创建新增“事件”表单,尝试将IncidentsType表的title字段值作为表单下拉选择框的选项。表单中能正常显示选项名称,但提交后在Admin面板中却显示为IncidentsType object(n)而非选项名称——比如提交时选择的是“Internet”,Admin中显示为IncidentsType object (3)。
我的模型代码
from django.db import models class NewUsers(models.Model): name = models.CharField(max_length=38) user_name = models.CharField(max_length=35) class NewIncidents(models.Model): tipo = models.CharField(max_length = 50) titulo = models.CharField(max_length = 200) resolucion = models.CharField(max_length = 300) class IncidentsType(models.Model): title = models.CharField(max_length = 200) subtitle = models.CharField(max_length = 200) description = models.CharField(max_length = 400)
我的表单代码
from django import forms from django.db import models from .models import NewIncidents, IncidentsType class IncidentForm(ModelForm): incidents = IncidentsType.objects.all() eleji = [] for incident in incidents: ttype = incident.title num = str(incident) conjunto = (num, ttype) eleji.append(conjunto) tipo = forms.ChoiceField(choices=eleji) class Meta: model = NewIncidents fields = ('tipo', 'titulo', 'resolucion') labels = { 'tipo': 'Tipo de Incidente:', 'titulo': 'Resumen del Incidente:', 'resolucion': 'Resolucion del Incidente:', } widgets = { 'tipo': forms.Select(attrs={'class' : 'form-control'}), 'titulo': forms.TextInput(attrs={'class' : 'form-control'}), 'resolucion': forms.TextInput(attrs={'class' : 'form-control'}), }
解决方案
1. 修正模型关联关系
NewIncidents的tipo字段不应使用CharField,而是用ForeignKey关联IncidentsType,这样才能正确存储对象关联而非字符串:
class NewIncidents(models.Model): # 关联IncidentsType,on_delete根据业务需求选择(如CASCADE/PROTECT) tipo = models.ForeignKey(IncidentsType, on_delete=models.CASCADE, verbose_name="Tipo de Incidente") titulo = models.CharField(max_length=200) resolucion = models.CharField(max_length=300)
2. 给IncidentsType添加__str__方法
默认情况下Django模型对象的字符串表示是ModelName object(n),添加__str__方法可以让Admin和表单显示title字段的值:
class IncidentsType(models.Model): title = models.CharField(max_length=200) subtitle = models.CharField(max_length=200) description = models.CharField(max_length=400) def __str__(self): return self.title
3. 简化表单代码
不需要手动生成下拉选项,ModelForm会自动处理ForeignKey对应的下拉选择框,简化后的表单代码如下:
from django import forms from .models import NewIncidents class IncidentForm(forms.ModelForm): class Meta: model = NewIncidents fields = ('tipo', 'titulo', 'resolucion') labels = { 'tipo': 'Tipo de Incidente:', 'titulo': 'Resumen del Incidente:', 'resolucion': 'Resolucion del Incidente:', } widgets = { 'tipo': forms.Select(attrs={'class': 'form-control'}), 'titulo': forms.TextInput(attrs={'class': 'form-control'}), 'resolucion': forms.TextInput(attrs={'class': 'form-control'}), }
问题原因说明
原来的代码中,你把IncidentsType对象的默认字符串表示(即IncidentsType object(n))存在了CharField中,所以Admin显示的就是这个存储的字符串。改成ForeignKey后,存储的是关联对象的ID,配合__str__方法,Django会自动在Admin和表单中显示title字段的值,同时保证数据关联的正确性。
内容的提问来源于stack exchange,提问作者Juan Vazquez
相关产品推荐
相关产品推荐

