如何修改管理页面上的选择 - django

sha*_*nyu 9 python django django-models django-admin

我的模型有一个名为"state"的字段:

class Foo(models.Model):
    ...
    state = models.IntegerField(choices = STATES)
    ...
Run Code Online (Sandbox Code Playgroud)

对于每个州,可能的选择是所有州的某个子集.例如:

if foo.state == STATES.OPEN:     #if foo is open, possible states are CLOSED, CANCELED
    ...
if foo.state == STATES.PENDING:  #if foo is pending, possible states are OPEN,CANCELED
    ...
Run Code Online (Sandbox Code Playgroud)

因此,当foo.state更改为新状态时,其可能的选择集也会更改.

如何在管理员添加/更改页面上实现此功能?

chk*_*chk 13

为模型创建新的管理界面(例如MyModelAdmin)时,有一些特定的方法可以覆盖字段的默认选项.对于通用选择字段:

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_choice_field(self, db_field, request, **kwargs):
        if db_field.name == "status":
            kwargs['choices'] = (
                ('accepted', 'Accepted'),
                ('denied', 'Denied'),
            )
            if request.user.is_superuser:
                kwargs['choices'] += (('ready', 'Ready for deployment'),)
        return super(MyModelAdmin, self).formfield_for_choice_field(db_field, request, **kwargs)
Run Code Online (Sandbox Code Playgroud)

但您也可以覆盖ForeignKeyMany to Many关系的选项.


Car*_*yer 9

您需要在ModelAdmin类中为该模型使用自定义ModelForm.在自定义ModelForm的__init__方法中,您可以动态设置该字段的选项:

class FooForm(forms.ModelForm):
    class Meta:
        model = Foo

    def __init__(self, *args, **kwargs):
        super(FooForm, self).__init__(*args, **kwargs)
        current_state = self.instance.state
        ...construct available_choices based on current state...
        self.fields['state'].choices = available_choices
Run Code Online (Sandbox Code Playgroud)

你会这样使用它:

class FooAdmin(admin.ModelAdmin):
    form = FooForm
Run Code Online (Sandbox Code Playgroud)