Django - Измененная форма администратора, возвращающая объект вместо текста
Я пытаюсь настроить форму администратора на Django-сайте таким образом, чтобы одно из полей превратилось из текстового поля в виджет выбора, предварительно заполненный путем захвата всех серийных номеров из таблицы мест (каждое имеет уникальный номер).
forms.py
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)
admin.py
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 Admin Form
HTML выглядит нормально: [HTML-картинка] (https://i.stack.imgur.com/n4eqG.png)
Но в базе данных отображается "object(1)", который вставляется вместе с остальными полями. Это должен быть серийный номер, извлеченный из тега select. Строка базы данных
Есть ли намеки на то, почему это происходит?
Непонятно, откуда взято третье изображение (изображение базы данных), но Class object (id)
- это формат, который Django использует по умолчанию для представления экземпляров Model.
Если вы хотите изменить это, вы можете переопределить __str__
метод вашего Model
класса.
В качестве примера, вот как может выглядеть ваш Location
класс:
class Location(models.Model):
# Some fields including sgln and name
def __str__(self):
return self.sgln + ":" + self.name
Теперь, если вы попытаетесь напечатать экземпляр модели Location
, то вместо Location object (<id>)
будет выведен результат self.sgln + ":" + self.name
.
Проблема в том, что вы используете 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,
)