我想在 django-admin 仪表板中使用链式过滤器,请帮助我实现它。 我有 3 个模型:- 董事会、年级和章节。 最初,当加载仪表板时,只有板过滤器应该出现,在选择板过滤器之后,所有选定的板都应该出现过滤器,在选择年级后,应该显示该年级的所有章节。
我试过 RelatedDropdownFilter,但那很正常, 它不修改 dropdownfilter 的 View 部分,它显示所有结果。
我的模型:-
class LmsBoard(models.Model):
name = models.CharField(max_length=240)
class LmsGrade(models.Model):
name = models.CharField(max_length=240)
board = models.ForeignKey(LmsBoard, models.DO_NOTHING)
class LmsSubject(models.Model):
name = models.CharField(max_length=240)
grade = models.ForeignKey(LmsGrade, models.DO_NOTHING)
board = models.ForeignKey(LmsBoard,models.DO_NOTHING)
class LmsChapter(models.Model):
name = models.CharField(max_length=240,default='None')
subject = models.ForeignKey(LmsSubject, models.DO_NOTHING)
我的 admin.py:-
@admin.register(MyModel)
class MyModel(admin.ModelAdmin):
list_display = (
'board', 'grade', 'chapter',)
list_filter = (
('board',RelatedDropdownFilter),
('grade', RelatedDropdownFilter),
('chapter', RelatedDropdownFilter),
我希望过滤器应该一个接一个地出现,并且应该包含最后选择的项目的过滤器列表。
请您参考如下方法:
我明白了,我只是举个例子
在简化的形式中,它看起来像:
class Website(models.Model):
url = models.URLField(unique=True)
class Page(models.Model):
website = models.ForeignKey(
'Website',
on_delete=models.CASCADE,
related_name='pages'
)
url = models.URLField(max_length=2083)
title = models.CharField(max_length=255)
content = models.TextField()
我在 admin.py 中设置了一个管理面板,如下所示:
from django.contrib.admin import ModelAdmin
class WebsiteAdmin(AdminViews):
actions = [scrape_website]
list_display = ['url']
search_fields = ['url']
现在我要做的是在右侧边栏中添加一个过滤器。它将允许我按已抓取/未抓取状态过滤网站。我认为“已抓取”是指网站在数据库中至少有一个页面,“未抓取”是指没有任何页面保存在数据库中的网站。
这是我们需要为 Django 管理员创建自定义过滤器的地方。就像 Django 的许多事情一样,它简单得可笑,跟着我的手:
from django.contrib.admin import ModelAdmin, SimpleListFilter
class ScrapeStatusFilter(SimpleListFilter):
title = 'Scrape status' # a label for our filter
parameter_name = 'pages' # you can put anything here
def lookups(self, request, model_admin):
# This is where you create filter options; we have two:
return [
('scraped', 'Scraped'),
('not_scraped', 'Not scraped'),
]
def queryset(self, request, queryset):
# This is where you process parameters selected by use via filter options:
if self.value() == 'scraped':
# Get websites that have at least one page.
return queryset.distinct().filter(pages__isnull=False)
if self.value():
# Get websites that don't have any pages.
return queryset.distinct().filter(pages__isnull=True)
最后一步是将 ScrapeStatusFilter 添加到 WebsiteAdmin:
class WebsiteAdmin(AdminViews):
actions = [scrape_website]
list_display = ['url']
search_fields = ['url']
list_filter = (ScrapeStatusFilter, )
应该就是这样。您现在可以通过自定义过滤器过滤网站列表。
