如果在下拉列表中选择了特定值,则 Django 管理员显示/隐藏字段

Posted

技术标签:

【中文标题】如果在下拉列表中选择了特定值,则 Django 管理员显示/隐藏字段【英文标题】:Django Admin Show / Hide Fields If Specific Value Is Selected In A Dropdown 【发布时间】:2018-05-30 00:01:49 【问题描述】:

在 Django 管理员中,当从下拉列表中选择 Custom 选项时,我想显示内联 start_dateend_date 字段以允许用户指定特定的开始和结束日期,而不是预定义的时间段。

经过一段时间的研究,建议包括:使用隐藏字段,在ModelAdmin中定义覆盖get_form,或者使用自定义javascript(我零经验)。

问题:当在 Django Admin 字段的下拉列表中选择特定值 (Custom) 时,如何显示(显示)内联 start_dateend_date 字段?当Custom没有被选中时,start_dateend_date会被隐藏起来。


第 1 步:

第 2 步:

第 3 步:


以下是我在本地拥有的确切示例代码的完整示例:

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    ...
    'dropdown.apps.DropdownConfig',
]

apps.py

from django.apps import AppConfig

class DropdownConfig(AppConfig):
    name = 'dropdown'

models.py

from django.db import models

class DropdownModel(models.Model):

    CHOICES = (
        ('Today', 'Today'),
        ('Yesterday', 'Yesterday'),
        ('Last 7 Days', 'Last 7 Days'),
        ('Last 14 Days', 'Last 14 Days'),
        ('Last 30 Days', 'Last 30 Days'),
        ('Last 60 Days', 'Last 60 Days'),
        ('Last 90 Days', 'Last 90 Days'),
        ('This Year', 'This Year'),
        ('All Time', 'All Time'),
        ('Custom', 'Custom')
    )

    date_range = models.CharField(max_length=15)
    start_date = models.DateField()
    end_date = models.DateField()

forms.py

from django import forms
from dropdown.models import DropdownModel

class DropdownModelForm(forms.ModelForm):

    class Meta:
        model = DropdownModel
        fields = ('date_range',)
        widgets = 
            'date_range': forms.Select(choices=DropdownModel.CHOICES)
        

admin.py

from django.contrib import admin
from dropdown.models import DropdownModel
from dropdown.forms import DropdownModelForm

class DropdownModelAdmin(admin.ModelAdmin):
    fieldsets = (
        ('Date Range', 
            'fields': ('date_range', ('start_date', 'end_date'))
        ),
    )
    form = DropdownModelForm

admin.site.register(DropdownModel, DropdownModelAdmin)

【问题讨论】:

我不认为你会逃避拥有一个自定义 JS.... 看看***.com/questions/18678711/… 好吧,如果您的目标是实时隐藏和显示,Javascript (AJAX) 不是一个选项,它实际上是强制性的。我看不到任何内置 Django 功能的方法可以让您实现这一目标。 【参考方案1】:

此问题的目的:如果在 Django 管理表单下拉列表中选择了特定选项,则显示/隐藏字段集。

解决方案概述:您需要将字段集分成两个而不是一个,自定义 javascript,在 ModelAdmin 中定义 Media 类。

[第一步]在我名为dropdown的项目中,我添加了以下文件夹/文件:

静态(目录) 静态/下拉(目录) 静态/下拉/js(目录) static/dropdown/js/base.js(文件)

[第二步]在admin.py中,有几点需要注意:

    我将fieldsets 分成两部分而不是一部分。 请注意,我正在为每个字段集定义classesabcdefg 是我要显示和隐藏的字段集的类的名称。 我定义了class Media。这告诉 django 在哪里寻找自定义的 javascript 和 css 文件。

admin.py

from django.contrib import admin
from dropdown.models import DropdownModel
from dropdown.forms import DropdownModelForm

class DropdownModelAdmin(admin.ModelAdmin):

    fieldsets = (
        ('Date Range', 
            'fields': ('date_range',),
            'classes': ('predefined',)
        ),
        (None, 
            'fields': (('start_date', 'end_date'),),
            'classes': ('abcdefg',)
        )
    )

    form = DropdownModelForm

    class Media:
        js = ('dropdown/js/base.js',)

admin.site.register(DropdownModel, DropdownModelAdmin)

[第三步] 添加javascript。 我不相信这个剧本;我只是从here稍微修改了一下。

base.js

(function($) 
    $(function() 
        var selectField = $('#id_date_range'),
            verified = $('.abcdefg');

        function toggleVerified(value) 
            if (value === 'Custom') 
                verified.show();
             else 
                verified.hide();
            
        

        // show/hide on load based on existing value of selectField
        toggleVerified(selectField.val());

        // show/hide on change
        selectField.change(function() 
            toggleVerified($(this).val());
        );
    );
)(django.jQuery);

[第四步]

forms.py

from django import forms
from dropdown.models import DropdownModel

class DropdownModelForm(forms.ModelForm):

    class Meta:
        model = DropdownModel
        fields = ('date_range',)
        widgets = 
            'date_range': forms.Select(choices=DropdownModel.CHOICES)
        

【讨论】:

刚刚用过这个解决方案!像魅力一样工作:-) 你从哪里得到 id 来填充 var selectField = $('#id_date_range') ? id_date_range 是日期范围字段的 html id 吗? 是的,你是对的。每个表单字段都有一个 ID 属性设置为 id_ 是否可以在 StackedInline 类中使用您的方法?我正在尝试完全相同,但在我的管理页面的选项卡中。到目前为止我还没有成功。似乎 Javascript 没有检测到我的字段集类,因此没有有条件地显示或隐藏。 解决了我的问题:我的 django 项目没有正确加载静态文件“base.js”...该解决方案的作用就像内联的魅力!

以上是关于如果在下拉列表中选择了特定值,则 Django 管理员显示/隐藏字段的主要内容,如果未能解决你的问题,请参考以下文章

如果选择了特定的选择选项值,则显示 div

在Django中用数据库值填充下拉列表后如何给它一个特定的值?

如果我在另一个下拉列表中选择特定值,我想将值添加到下拉列表

Django:如何创建类别字段/下拉菜单?

在 Django 中,根据模型中其他字段中选择的值删除选择字段下拉列表中的选项

在下拉列表中选择特定值时如何在联系表单 7 中启用字段