Search code examples
pythondjangodjango-modelsdjango-formsdjango-admin

Django - Modified Admin Form Returning an Object Instead of Text


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)

Solution

  • 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>).