如何修改Django Admin中的选项

10 投票
5 回答
13372 浏览
提问于 2025-04-15 11:35

我有一个模型,它里面有一个叫“state”的字段:

class Foo(models.Model):
    ...
    state = models.IntegerField(choices = STATES)
    ...

对于每个状态,可能的选择是所有状态中的一个特定子集。例如:

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
    ...

因此,当 foo.state 变成一个新状态时,它的可能选择也会随之改变。

我该如何在管理后台的添加或修改页面上实现这个功能呢?

5 个回答

0

这看起来是个需要用到JavaScript的活。你想让下拉框里的选项根据其他东西的值来变化,那个东西可能是复选框或者单选按钮。要做到这一点,让它动态变化——也就是说,不用让用户保存表单然后重新加载页面——就得用JavaScript。

你可以通过使用ModelAdmin的Media类,在模型的管理页面加载自定义的JavaScript,具体的说明可以在这里找到。

18

当你为一个模型(比如说 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)

不过,你也可以改变 外键多对多 关系的选项。

13

你需要在这个模型的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

你可以这样使用它:

class FooAdmin(admin.ModelAdmin):
    form = FooForm

撰写回答