You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 00:45:25