我的模型有一个名为“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更改为新状态时,其可能的选择集也会更改。
如何在管理员添加/更改页面上实现此功能?
答案 0 :(得分:12)
为模型创建新的管理界面(例如MyModelAdmin)时,有一些特定的方法可以覆盖字段的默认选项。对于通用choice field:
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)
但您也可以覆盖ForeignKey和Many to Many关系的选择。
答案 1 :(得分:9)
您需要在该模型的ModelAdmin类中use a custom 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
答案 2 :(得分:0)
这似乎是一些javascript的工作。您希望选择框中的项目列表根据其他内容的值进行更改,这可能是复选框或单选按钮。使动态发生的唯一方法是 - 无需用户保存表单并重新加载页面 - 将使用javascript。
您可以使用ModelAdmin的Media类(文档here)在模型的管理页面中加载自定义javascript。
答案 3 :(得分:-1)
我看到你正在尝试做什么,但为什么不只是显示所有这些,如果这个人选择(已设置)当前状态,只是不改变任何东西?
您也可以使用表单构建视图以提供此功能