2

我有Chart和 Module 模型(见下面的代码)。每个图表都属于一个模块(通过 a 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)
4

2 回答 2

3

只需覆盖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
    ...
于 2012-03-15T15:22:45.013 回答
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)
于 2012-03-15T15:00:25.103 回答