Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i get a dropdown for a CharField in Wagtail Admin?

In Django Admin, it is possible to add a dropdown selector with all possible enum values like this example:

class ThesisStatus(models.TextChoices):
    OPEN = 'O', _('Offen')
    TAKEN = 'T', _('Vergeben')
    WORK_IN_PROGRESS = 'W', _('In Arbeit')
    COMPLETED = 'C', _('Komplett')
    ABORTED = 'A', _('Abgebrochen')

status = models.CharField(
    max_length=1,
    choices=ThesisStatus.choices,
    default=ThesisStatus.OPEN,
)

In wagtail, this does not work:

panels = [
   FieldPanel('status'),
]

if the field is a CharField, but it does work for a TextField. How can I fix or implement this for CharField?

like image 333
fwinterl Avatar asked Oct 24 '25 17:10

fwinterl


1 Answers

The code above works fine when using CharField so I have assumed you want to get this working with TextField instead.

When defining a Django model's field, each field comes with a default widget, CharField has some smarter handling for when choices is provided to the field and uses the Select widget.

However, the TextField's default widget is the TextArea so you need to provide Wagtail with the widget you want to use.

Widgets are a Django term for how to present the field as a HTML field, the Select widget is what you want to use for a drop-down but there are many other build in widgets.

Finally, to tell Wagtail what widget to use for the FieldPanel you need to pass in a widget kwarg.

After this, you should see that the UI will show a select drop down but will be stored as a TextField in the database.

Example: models.py

from django import forms
from django.db import models

class MyPage(Page):
    # ... other fields

    class ThesisStatus(models.TextChoices):
        OPEN = "O", "Offen"
        TAKEN = "T", "Vergeben"
        WORK_IN_PROGRESS = "W", "In Arbeit"
        COMPLETED = "C", "Komplett"
        ABORTED = "A", "Abgebrochen"
    
    # note: using `models.TextField` here
    status = models.TextField(
        max_length=1,
        choices=ThesisStatus.choices,
        default=ThesisStatus.OPEN,
    )

    content_panels = Page.content_panels + [
        FieldPanel("status", widget=forms.Select), # note: using widget here
        # ... other panels
        ]

Docs Links

  • Django Fields (Choices)
  • Django Fields (TextField)
  • Django Widgets (Select)
  • Wagtail FieldPanel
like image 57
LB Ben Johnston Avatar answered Oct 26 '25 05:10

LB Ben Johnston