Skip to main content
 首页 » 编程设计

python之如何在 Django 管理仪表板中构建链式过滤器

2024年11月01日35开发

我想在 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, ) 

应该就是这样。您现在可以通过自定义过滤器过滤网站列表。