簡體   English   中英

Django Admin-通過模型過濾ManyToManyField

[英]Django Admin - Filter ManyToManyField with through model

如何在具有ManyToManyField關系且through模型手動定義的對象的“管理”頁面內過濾查詢集?

給定models.py

class Foo(models.Model):
    foo_field1 = models.CharField(max_length=50)

class Main(models.Model):
    main_field1 = models.CharField(max_length=50)
    m2mfield = models.ManyToManyField(Foo, through="FooBar")

class FooBar(models.Model):
    main = models.ForeignKey(Main, on_delete=models.CASCADE)
    foo = models.ForeignKey(Foo, on_delete=models.CASCADE)
    new_field = models.CharField(max_length=50)

內部admin.py

class M2MInlineAdmin(admin.TabularInline):
    model = Main.m2mfield.through
    extra = 1

class MainAdmin(admin.ModelAdmin):
   inlines = [M2MInlineAdmin,]
   ...

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        print('called formfield_for_manytomany')
        return super().formfield_for_manytomany(db_field, request, **kwargs)

    def get_field_queryset(self, db, db_field, request):
        print('called get_field_queryset')
        return super().get_field_queryset(db, db_field, request)

我嘗試訪問這兩種方法,但是如果指定了through表,則不會調用它們。 但是,如果將ManyToMany關系簡單定義為:

class Main(models.Model):
    main_field1 = models.CharField(max_length=50)
    m2mfield = models.ManyToManyField(Foo)

指定通過表(同時能夠訪問request上下文)時,是否有一種方法可以過濾request

編輯:

當ManyToManyField有一個方法確實叫through指定的模型,只有當沒有fieldsets里面指定modelAdmin類。

定義fieldsets時如何訪問這些方法?

您可以formfield_for_foreignkey()聯類上使用formfield_for_foreignkey()方法。

class M2MInlineAdmin(admin.TabularInline):
    model = Main.m2mfield.through
    extra = 1

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "car":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

僅當使用默認格式時,才會調用 formfield_for_manytomany方法。 定義字段集時,它使用的是另一種形式,這就是為什么上面的方法沒有被調用的原因。

由於您對許多字段使用表格管理,因此可以覆蓋get_queryset以使用字段進行過濾。

class M2MInlineAdmin(admin.TabularInline):
    model = Main.fruits.through
    extra = 1

    def get_queryset(self, request):
        qs = super(M2MInlineAdmin, self).get_queryset(request)
        qs = qs.filter(some_arg=some_value)
        return qs

或者,您可以編寫自定義模型表單並在admin(而不是默認表單)中使用它。

class MainAdminForm(forms.ModelForm):

    class Meta:
        model = Main
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # custom setup


class MainAdmin(admin.ModelAdmin):
    form = MainAdminForm

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM