【问题标题】:Can I filter options automatically on the Django Admin "add" page?我可以在 Django Admin“添加”页面上自动过滤选项吗?
【发布时间】:2020-05-29 00:25:13
【问题描述】:

考虑一个 Word-A-Day Django webapp,它每天向用户展示一个词汇单词,单词的难度从星期一的“普通”增加到星期五的“晦涩”。

models.py 中的模型如下所示:

class WordADay(models.Model):
    """A vocabulary word and its assigned day"""

    date = models.DateField(
        help_text="The date to post the selected word"
    )
    word = models.ForeignKey(
        Words,
        help_text="The selected vocabulary word"
    )

class Word(models.Model):
    """Vocabulary words"""

    OBSCURITY_CHOICES = [(1,'Monday'),
                         (2,'Tuesday'),
                         (3,'Wednesday'),
                         (4,'Thursday'),
                         (5,'Friday')]

    word = models.CharField(
        max_length=32,
        help_text="A vocabulary word"
    )
    difficulty = models.PositiveSmallIntegerField(
        choices=OBSCURITY_CHOICES,
        help_text="How obscure the word is"
    )

在 WordADay 模型的管理员“添加”页面上,我希望能够首先从标准日历选择器中为“日期”字段选择一天。选择后,我希望“单词”字段的下拉选择器中的选项自动过滤到仅具有正确难度的 Word 模型实例,“1”对应于星期一日期,“ 5" 对应于星期五日期。也就是说,我想根据为不同字段选择的值过滤外键选项。

为了便于讨论,我可以提供一个骨架admin.py

from django.contrib import admin
from .models import WordADay, Word
from django.db import models

@admin.register(WordADay)
class WordADayAdmin(admin.ModelAdmin):
    pass

@admin.register(Word)
class WordAdmin(admin.ModelAdmin):
    pass

虽然它当然不完整,因为我不知道该放什么。

在阅读文档几个小时后,我找到了list_filter 属性,描述为

设置 list_filter 以激活管理员更改列表页面右侧边栏中的过滤器

这不是我想要的;我想要“添加”页面上的过滤器,而不是“更改”页面,并且我不想要侧边栏,我希望在选择日期后自动过滤。

如果不从头创建新的 AdminSite,这是否可能?

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    这不是 django-admin 中的任何内置功能要做的事情。但是,您不必完全从头开始创建一个全新的管理站点。

    最好的方法是使用 javascript 来更新相关表单值的值。您需要在其中一个输入的更改事件上添加一个事件侦听器,并将其设置为更新另一个。

    因为 django-admin 在一两个地方使用 jquery,所以您可以免费访问 jquery,或者使用纯 JavaScript 相对容易。

    就如何将 javascript 附加到此页面而言,您有两种选择:

    1. 通过你的modelAdmin加载javascript)
    class MyAdmin(admin.ModelAdmin):
        class Media:
            js = ('js/my_script.js', ) # this should be a file from your static directory
    
    1. 扩展模板。
    class MyAdmin(admin.ModelAdmin):
        change_form_template = "my_template.html"
    

    然后在my_template.html

    {% extends "admin/change_form.html" %}
    {% block %}
    {% block extrahead %}
    {{ block.super }}
      ... add your script here
    {% endblock %}
    

    第二个选项的优点是您可以根据通过上下文加载的值更改脚本,但这可能不是必需的。

    【讨论】:

    • 我想将此添加到“添加”页面,而不是“更改”页面。两者的模板是否相同 (change_form.html)?
    • @DarienMarks 还有一个add_form_template 属性,但我相信如果它未设置,change_form_template 将被使用。
    • 好的,谢谢!这需要我一点时间来实现,有结果我会回来的。
    • 我可以确认这两种方法都有效。我最初尝试了 2.,但正如您也回答的 another question 中所述,使用日历选择器尤其会引入额外的 JavaScript 复杂性。我最终通过方法 1 让它更顺利地工作。应用于一个新的小部件。再次感谢!
    • 你比我们更受欢迎 :) 很高兴你成功了
    猜你喜欢
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 2018-03-31
    • 2021-06-11
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    相关资源
    最近更新 更多