与Inline相关的ManyToMany上的Django limit_choices_to

时间:2016-03-03 17:42:10

标签: python django

我想使用limit_choices_to在使用内联时使用ManyToMany Field减少模型的Django管理员的选择集。

有趣的是,我想限制选择的原因在于性能,因为我想在我的相关模型类的__str__方法中使用父模型的属性,而不限制选择导致过多的SQL查询。

以下作品

class ParentOfA(models.Model):
    name = models.CharField(max_length=50, null=True)


class A(models.Model):
    parent = models.ForeignKey(ParentOfA)

    def __str__(self):
        return "%s" % self.parent


class B(models.Model):
    a = models.ManyToManyField(A, limit_choices_to={"a__name":'parent name'})

如果我没有在B的管理表单中使用内联(在示例in the docs之后)。

E.g。

@admin.register(B)
class BAdmin(admin.ModelAdmin):
    pass

但是,使用内联limit_choices_to无效:

class BInline(admin.TabularInline):
    model = B.A.through

@admin.register(B)
class BAdmin(admin.ModelAdmin):
    inline = (BInline,)

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

我不知道为什么limit_choices_to不适用于内联字段,我遇到了同样的问题。虽然这不是必需的,但您可以使用以下答案限制内联中字段的查询集:https://stackoverflow.com/a/4236159/1302095

这是旧问题的旧答案,所以我不确定在较新版本的django中是否有更好的方法。我使用1.8.3并且它有效,这对我来说很重要!

此处粘贴的代码仅供参考:

class RoomInline(admin.TabularInline):
    model = Room

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        field = super(RoomInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

        if db_field.name == 'inside_room':
            if request._obj_ is not None:
                field.queryset = field.queryset.filter(building__exact = request._obj_)  
            else:
                field.queryset = field.queryset.none()

        return field

class BuildingAdmin(admin.ModelAdmin):
    inlines = (RoomInline,)

    def get_form(self, request, obj=None, **kwargs):
        # just save obj reference for future processing in Inline
        request._obj_ = obj
        return super(BuildingAdmin, self).get_form(request, obj, **kwargs)