[Django]-Django admin – how to change choices in inlines?

5πŸ‘

if your field is a IntegerField or Charfield with the choices attribute, you can override the formfield_for_choice_field method in your inline class with something like this:

class YourInline(admin.StackedInline): # or TabularInline
    model = YourModelName

    def formfield_for_choice_field(self, db_field, request=None, **kwargs):
        if db_field.name == 'YOUR_FIELD_NAME':
            kwargs['choices'] = (('', '---------'), ('1', 'Choice1'), ('2', 'Choice2'))
        return db_field.formfield(**kwargs)

good luck

2πŸ‘

in my case, the form option must be filled, hope help anyone.

# admin.py
class YourInlineForm(forms.ModelForm):
    class Meta:
        fields = '__all__'
        model = YourModelName
        widgets = {
            'level': forms.widgets.Select(
                choices = (
                    (0,'A'),
                    (1,'B'),
                    (2,'C'),
                ),
            )
        }

# admin.py
class YourInline(admin.StackedInline): # or TabularInline
    model = YourModelName
    form = YourInlineForm

    def formfield_for_choice_field(self, db_field, request=None, **kwargs):
        if db_field.name == 'YOUR_FIELD_NAME':
            kwargs['choices'] = (('', '---------'), ('1', 'Choice1'), ('2', 'Choice2'))
        return db_field.formfield(**kwargs)

1πŸ‘

I agree with eos87’s answer. It is only a partial solution however. When saving, a validation error occurs since the original model’s choices are being used for validation. To solve that problem, add this function to your model as well:

def clean_fields(self, exclude=None):
    exclude.append('YOUR_FIELD_NAME') # we will do our own validation on this field
    super(YOUR_MODEL, self).clean_fields(exclude = exclude)

    value = self.YOUR_FIELD_NAME
    if value and not self.validChoice(value):
        msg = 'Select a valid choice. %s is not one of the available choices.'
        errors = {''YOUR_FIELD_NAME'': ([msg % value])}
        raise ValidationError(errors)

def validChoice(self, value):
  # add your validation code here

Leave a comment