[英]how to override django admin form Foreignkey based on request.user
[英]Django admin: how do I filter a ForeignKeyField widget based on the object's (not request.user's) data?
我有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)
只需覆盖正在使用的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
...
根据我在源代码中看到的内容,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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.