Software Developer in Illinois

Dynamically update Django form choice labels

· June 05, 2017 · Django ·

Let's say you have a form with a ChoiceField populated with preset options, but you want to make the choices more specific to the user.

For example, you want to ask the user to select if they like their favorite book or their favorite movie more. Let's say for some users, you already know their favorite book and for those users you want to display the book's title instead of a generic "Your favorite book" label.

I had trouble initially finding a solution for this situation, so thought I would share what I ended up doing.

In your form's class method, override the __init__ method with an additional optional argument specifying the favorite book...


class FavoriteThingForm(forms.Form):

    favorite_book_label = 'Your favorite book'
    favorite_movie_label = 'Your favorite movie'
    favorite_choices = [
        ('book', favorite_book_label),
        ('movie', favorite_movie_label)
    ]
    
    favorite_thing_choice = forms.ChoiceField(
        label=('What do you like more?'),
        choices=favorite_choices,
        widget=forms.RadioSelect
    )

    def __init__(self, favorite_book=None, *args, **kwargs):
        super(ExampleForm, self).__init__(*args, **kwargs)
        if favorite_book:
            # Overwrite labels
            self.fields['favorite_thing_choice'].choices = [
                ('book', favorite_book),
                ('movie', self.favorite_movie_label)
            ] 

And then in your view, pass the user's favorite book - if it exists - to the form using get_form_kwargs...


class FavoriteSelectionView(FormView):
    form_class = FavoriteThingForm
    
    def get_form_kwargs(self):
        kwargs = super(FavoriteSelectionView, self).get_form_kwargs()
        if user.favorite_book:
            kwargs['favorite_book'] = user.favorite_book
        return kwargs

And that's it. Now users with a favorite book will see it listed as a choice, while others will see the generic "Your favorite book" option.

Next
Reaching nearly 200 reviews in 8 days with SKStoreReviewController

© Michael Schmitt