Django - 修改的管理表单返回对象而非文本
我正在尝试在一个Django网站上自定义一个管理员表单,希望把其中一个字段从文本框改成一个下拉选择框,这个下拉框的选项是从一个地点表中获取的所有序列号(每个地点都有一个独特的编号)。
这是表单的代码:
class SglnModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return obj.sgln + ":" + obj.name
class EndpointForm(forms.ModelForm):
sgln = SglnModelChoiceField(
queryset=Location.objects.all(),
to_field_name="sgln",
label="Endpoint SGLN",
required=True,
)
login = forms.CharField(label='Endpoint Login', max_length=32, required=True)
password = forms.CharField(label='Endpoint Password', max_length=32, required=True)
这是管理员的代码:
from django.contrib import admin
from .forms import EndpointForm
from .models import Endpoints
class EndpointAdmin(admin.ModelAdmin):
form = EndpointForm
admin.site.register(Endpoints, EndpointAdmin)
表单看起来不错:
Django管理员表单HTML也看起来不错:
[HTML picture] (https://i.stack.imgur.com/n4eqG.png)但是数据库中显示插入了一个“object(1)”的内容,和其他字段一起。这应该是从下拉框中选出的序列号。
数据库行有没有人能给点提示,为什么会这样?
更新 - 为了更清楚,我添加了一个简化的地点模型(不需要所有字段)和端点模型,但它们都是标准模型。
这是模型的代码:
class Location(models.Model):
sgln = models.CharField(max_length=15, unique=True)
name = models.CharField(max_length=64)
streetAddress = models.CharField(max_length=64)
suite = models.CharField(max_length=64)
city = models.CharField(max_length=32)
state = models.CharField(max_length=2)
postalCode = models.CharField(max_length=10)
class Endpoints(models.Model):
sgln = models.CharField(max_length=19, unique=True)
login = models.CharField('Endpoint Login ', max_length=32, default=None, null=True)
password = models.CharField('Endpoint Password', max_length=32, default=None, null=True)
tstamp = models.DateTimeField(auto_now_add=True)
2 个回答
1
问题在于你使用了一个 ModelChoiceField
来选择一个 CharField
的值。当你提交数据到 ModelChoiceField
时,它会把这个值转换成指定的模型实例。这种字段是用来处理模型中的外键的,而不是用在 CharField
上。对于你的情况,你应该使用一个 ChoiceField:
def get_sgln_choices():
return [
(location["sgln"], location["sgln"] + ":" + location["name"])
for location in Location.objects.values("sgln", "name")
]
class EndpointForm(forms.ModelForm):
sgln = ChoiceField(
choices=get_sgln_choices
label="Endpoint SGLN",
required=True,
)
0
第三张图片(数据库那张)来源不太明显,但Class object (id)
是Django默认用来表示模型实例的格式。
如果你想改变这个格式,可以重写你的Model
类中的__str__
方法。
举个例子,你的Location
类可以这样写:
class Location(models.Model):
# Some fields including sgln and name
def __str__(self):
return self.sgln + ":" + self.name
现在,如果你尝试打印一个Location
模型的实例,它会显示self.sgln + ":" + self.name
的结果,而不是Location object (<id>)
。