我有Chart
和模块模型(请参阅下面的代码)。每个图表都属于一个模块(通过ForeignKey
)。图表可能有另一个图表parent
(另一个ForeignKey
)。我在管理员中想要的是,parent
在特定图表上的下拉列表仅包含同一模块中的图表。
我正在寻找一个Python解决方案,而不是AJAX。这意味着在创建新图表时,下拉列表必须为空(没有模型实例,没有选择模块),并且更改管理模块中的模块将不会更新parent
选项以匹配,直到模型为保存。我很好。
根据用户,有很多类似的问题(和答案)可以过滤选项; ModelAdmin.formfield_for_foreignkey
将请求作为参数获取,因此您可以使用request.user
,但不会获得要使用的模型实例。 (我正在使用Django 1.3。)
我的模特(当然高度简化):
class Module(models.Model):
pass
class Chart(models.Model):
module = models.ForeignKey(Module)
parent = models.ForeignKey(Chart, blank=True, null=True)
class ChartAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
# I would like to do this, but have no "instance":
kwargs['queryset'] = Chart.objects.filter(module=instance.module)
return super(ChartAdmin, self).formfield_for_foreignkey(self, db_field, request, **kwargs)
admin.site.register(Chart, ChartAdmin)
答案 0 :(得分:2)
从我在源代码中看到的,kwargs应该只包含小部件(没有帮助!)。
一种可能的方法是覆盖get_form()modeladmin方法,只需设置request.current_object即可。然后,您可以在formfield_callback中使用request.current_object:
def get_form(self, request, obj=None, **kwargs):
request.current_object = obj
return super(ChartAdmin, self).get_form(request, obj, **kwargs)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
instance = request.current_object
kwargs['queryset'] = Chart.objects.filter(module=instance.module)
return super(ChartAdmin, self).formfield_for_foreignkey(self, db_field, request, **kwargs)
答案 1 :(得分:2)
只需覆盖正在使用的ModelForm
:
class ChartAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ChartAdminForm, self).__init__(*args, **kwargs)
if self.instance.module_id:
self.fields['parent'].queryset = self.fields['parent'].queryset.filter(module=self.instance.module)
class ChartAdmin(admin.ModelAdmin):
form = ChartAdminForm
...