fwinterl
fwinterl

Reputation: 105

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?

Upvotes: 4

Views: 2453

Answers (1)

LB Ben Johnston
LB Ben Johnston

Reputation: 5196

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

Upvotes: 5

Related Questions