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,
    )
Вернуться на верх