用于内联模型行的 Django 管理过滤器

问题描述 投票:0回答:1

我有一个父模型(作者)和内联模型(书籍)


class Author(models.Model):
    age = models.IntegerField()

class Book(models.Model):
    name = models.CharField(max_length=250)
    price = models.CharField(max_length=250)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

书籍模型有3行

为了传达我的问题,我以可读的字典格式提供 UI 结果

{id:1, name:'book1', price: 50, author_id: 1}
{id:2, name:'book2', price: 75, author_id: 1}
{id:3, name:'book1', price: 65, author_id: 2}

在 admin.py 中,我有 AuthorAdmin,它有一个列表过滤器,

list_filter = ['age', 'book__name', 'book__price']

在 django 管理列表视图页面中,如果我过滤 /admin/?book__name=book1&book__price=75

它给出作者(id = 1),作者(id = 2)作为结果

但它应该只返回 id:1 行。

请帮助如何在 django admin 中的 m2m 关系(内联)中使用 list_filter。

我使用__来过滤内联,但结果不准确。

我的理解是,如果至少 1 个内联项与查询匹配,django 将返回父级。我希望过滤器被链接起来。

python django django-admin m2m
1个回答
0
投票

要在 Django admin 中实现内联模型的链式过滤器的所需行为,您可以重写

get_search_results
类中的
AuthorAdmin
方法。此方法允许您自定义搜索和过滤查询的执行方式。

以下是如何实现您所描述的行为的示例:

from django.contrib import admin
from .models import Author, Book

class BookInline(admin.TabularInline):
    model = Book

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ['id', 'age']
    inlines = [BookInline]

    def get_search_results(self, request, queryset, search_term):
        # Split the search term into name and price parts
        name_filter, price_filter = search_term.split(',')
        # Perform separate searches for name and price
        name_results, name_use_distinct = super().get_search_results(
            request, queryset, name_filter.strip()
        )
        price_results, price_use_distinct = super().get_search_results(
            request, queryset, price_filter.strip()
        )
        # Combine the results using AND logic to get the desired behavior
        combined_results = name_results & price_results
        return combined_results, name_use_distinct or price_use_distinct

    search_fields = ['age']

    list_filter = [
        'age',
        ('book__name', admin.RelatedOnlyFieldListFilter),
        ('book__price', admin.RelatedOnlyFieldListFilter),
    ]

在上面的代码中:

  1. 我们定义了一个自定义的

    get_search_results
    方法来处理链式过滤器行为。它将搜索词拆分为名称和价格部分,对每个部分执行单独的搜索,然后使用 AND 逻辑组合结果以确保满足这两个条件。

  2. 我们为“年龄”字段指定

    search_fields
    以启用按年龄搜索。

  3. 我们使用

    admin.RelatedOnlyFieldListFilter
    作为“book__name”和“book__price”过滤器,以确保过滤器选项中仅显示相关值。

通过此自定义,当您使用

/admin/?book__name=book1&book__price=75
在 Django 管理中进行过滤时,它应该仅返回带有
Author
id=1
实例,因为它匹配两个条件(名称='book1'和价格=75)。

© www.soinside.com 2019 - 2024. All rights reserved.