Manuel Santi
Manuel Santi

Reputation: 1132

Django admin change field from text to combobox

In my models i have this class:

class temp_main(models.Model):
    descr = models.CharField(max_length=200, verbose_name="Description")
    notes = models.TextField(null=True, blank=True, verbose_name="Note")
    dt = models.DateTimeField(auto_now=True, verbose_name="Created")
    owner = models.ForeignKey('auth.User', related_name='tmain_owner', on_delete=models.CASCADE, verbose_name="API Owner")

class Meta:
    verbose_name = '1-Main Template'
    verbose_name_plural = '1-Main Templates'


def __str__(self):
    return self.descr

Then in my admin.py

class temp_mainAdmin(admin.ModelAdmin):

    #list_filter = ('main_id__descr', 'l_type')
    list_display = ('descr', 'notes', 'dt')
    #ordering = ('-l_type',)

    def save_model(self, request, obj, form, change):
        obj.user = request.user
        super(temp_mainAdmin, self).save_model(request, obj, form, change)

    def changeform_view(self, request, obj_id, form_url, extra_context=None):

        l_mod = temp_main.objects.latest('id')

        extra_context = {
            'lmod': l_mod,
        }
        return super(temp_mainAdmin, self).changeform_view(request, obj_id, form_url, extra_context=extra_context)

all done but i would in add and edit form that my field descr (charfield) vas not displayed as a textbox but instead like a combobox with pre-defined key/val data like 1:'Descr1',2:Descr2' etc etc

How can i achieve this result in django admin add and edit form?

thanks in advance

Upvotes: 1

Views: 1632

Answers (1)

YellowShark
YellowShark

Reputation: 2269

You need to override the ModelAdmin.get_form() method, which will allow you to change the type of input field that Django uses by default for your descr field. Here's what it should look like:

from django.forms import SelectMultiple

class temp_mainAdmin(admin.ModelAdmin):
    # No changes to the code you provided above / this is all the same:

    #list_filter = ('main_id__descr', 'l_type')
    list_display = ('descr', 'notes', 'dt')
    #ordering = ('-l_type',)

    def save_model(self, request, obj, form, change):
        obj.user = request.user
        super(temp_mainAdmin, self).save_model(request, obj, form, change)

    def changeform_view(self, request, obj_id, form_url, extra_context=None):

        l_mod = temp_main.objects.latest('id')

        extra_context = {
            'lmod': l_mod,
        }
        return super(temp_mainAdmin, self).changeform_view(request, obj_id, form_url, extra_context=extra_context)

    # This is new - override the parent class's get_form method:
    def get_form(self, request, obj=None, **kwargs):
        # 1. Get the form from the parent class:
        form = super(temp_mainAdmin, self).get_form(request, obj, **kwargs)
        # 2. Change the widget:
        form.base_fields['descr'].widget = SelectMultiple(choices=(
            (1, 'Descr1'),
            (2, 'Descr2'),
        ))
        # 3. Return the form!
        return form

Upvotes: 2

Related Questions