我有一个父模型(作者)和内联模型(书籍)
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 将返回父级。我希望过滤器被链接起来。
要在 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),
]
在上面的代码中:
我们定义了一个自定义的
get_search_results
方法来处理链式过滤器行为。它将搜索词拆分为名称和价格部分,对每个部分执行单独的搜索,然后使用 AND 逻辑组合结果以确保满足这两个条件。
我们为“年龄”字段指定
search_fields
以启用按年龄搜索。
我们使用
admin.RelatedOnlyFieldListFilter
作为“book__name”和“book__price”过滤器,以确保过滤器选项中仅显示相关值。
通过此自定义,当您使用
/admin/?book__name=book1&book__price=75
在 Django 管理中进行过滤时,它应该仅返回带有 Author
的 id=1
实例,因为它匹配两个条件(名称='book1'和价格=75)。