I am trying to customize an Admin form on a Django site so that one of the fields is changed from a text field to a select widget pre-populated by grabbing all the serial numbers from a table of locations (each has a unique number).
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)
The form looks fine: Django Admin Form
The HTML looks fine: [HTML picture] (https://i.sstatic.net/n4eqG.png)
But the database is showing a "object(1)" as being inserted along with the rest of the fields. This should be a serial number pulled form the select tag. Database row
Any hints as to why this is happening?
Update - just for clarity I added a simplified Location model (no need to have all the fields) and the Endpoint model but they are just standard models.
models.py
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)
It is not obvious where the third image (the database one) is taken from, but the Class object (id)
is the default format Django uses to represent Model instances.
If you want that changed, you can override the __str__
method of your Model
class.
As an example, this can be how your Location
class looks like:
class Location(models.Model):
# Some fields including sgln and name
def __str__(self):
return self.sgln + ":" + self.name
Now if you try to print an instance of Location
model, it will print the result of self.sgln + ":" + self.name
instead of Location object (<id>)
.