在Django admin中更改日期字段的默认小部件

时间:2011-12-15 07:09:29

标签: django datepicker admin

如何在Django ADMIN中更改DateField实例的默认小部件?

我知道如何为ModelForm执行此操作 - How do you change the default widget for all Django date fields in a ModelForm? - 通过提供检查字段类型的formfield_callback,然后使用新窗口小部件提供表单字段。

但是,我的一些ModelAdmin可能已经有一个自定义的ModelForm,有些则没有。我不想在有日期字段的任何地方提供/更改ModelForm(这就是要点)。

可以用于子类化的自定义ModelAdmin可以。 ModelAdmin如何更改其表单的日期字段,与是否提供自定义ModelForm无关?

也许是一个带有get_form()的ModelAdmin调用它的超级然后设置表单的formfield_callback?看起来有点复杂,不确定时间,如果任何ModelAdmin需要进一步定制,还有三件事要注意......

P.S。:我在https://stackoverflow.com/questions/8484811/jquery-datepicker-in-django-admin被错误地关闭后因为与上述ModelForm问题的“完全重复”而要求这样做。我希望现在的区别很明显。

顺便说一下,我的个人动机是django admin默认日期选择器的年份导航。生日真的很糟糕...... :-)是的,有一张三年票[{3}}

2 个答案:

答案 0 :(得分:1)

ModelAdmin只能更改它呈现的表单的窗口小部件,因此很难覆盖传递给它的自定义窗体的窗口小部件 - 至少我想不出干净的方法来执行它。

我可以为您看一些选项,具体取决于您想要自定义的方式。

  1. 修改为小部件带来魔力的javascript。如果您可以在那里处理更改,这似乎很容易。只需提供您自己的js/calendar.jsjs/admin/DateTimeShortcuts.js,就像覆盖管理员模板一样。这有升级友好的额外好处;因为你没有修改django代码库;对于使用小部件的所有表单,也会立即进行更改。

  2. 自定义内置的django小部件以执行您想要的操作。这样做的好处是可以立即工作而无需对现有代码进行任何修改,但除非您小心修补源代码,否则无法升级。来源位于django.contrib.admin.widgets

  3. 提供您自己的自定义窗口小部件 - 但是您回到了解决代码问题并使用自定义窗口小部件手动覆盖所有窗口小部件实例的问题。

  4. 使用类似grappelli的内容并修改模板/ j以执行您想要的操作。这里添加的奖励是你将免费获得许多其他功能(例如,如果你使用django-admin-tools插入仪表板,就可以使用它。)

  5. django在他们的管理员中广泛使用jquery,他们有自己的jquery命名空间(django.jQuery);因此,如果您打算做一些自定义小部件,请确保使用正确的命名空间以避免出现奇怪的问题。

答案 1 :(得分:0)

我能够在Django管理员中自定义默认日期小部件。我遵循了两个教程(来自Simple is Better than ComplexDjango Custom Widget

  1. 在Django应用中名为widgets.py的文件中编写自定义窗口小部件
from django.forms import DateInput


class CustomDatePickerInput(DateInput):
    template_name = "app_name/widgets/custom_datepicker.html"

    class Media:
        css = {
            "all": (
                "https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css",
            )
        }
        js = (
            "https://code.jquery.com/jquery-3.4.1.min.js",
            "https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.js",
            "https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/i18n/datepicker.es-ES.min.js",
        )

请注意,您可能需要的CSS和JS文件应添加到内部Media类中,如上面的代码所示。在这种情况下,它将为自定义date picker添加样式。

  1. 定义窗口小部件的模板,有关日期选择器的更多选项,请参见here,将此文件放入app_name/templates/app_name/widgets/custom_datepicker.html或确保此模板与自定义窗口小部件中的template_name的值匹配:
{% load i18n %}

{% include "django/forms/widgets/input.html" %}
{% get_current_language as LANGUAGE_CODE %}

<script>
  $(function () {
    const DATE_PICKER_OPTIONS = {
      'en-us': {
        format: 'yyyy-mm-dd',
        language: ''
      },
      'es': {
        format: 'dd/mm/yyyy',
        language: 'es-ES'
      }
    };
    let options = DATE_PICKER_OPTIONS['{{ LANGUAGE_CODE }}'];
    $("input[name='{{ widget.name }}']").datepicker({
      format: options.format,
      language: options.language
    });
  });
</script>
  1. 在Django管理员中注册模型时,您需要在日期字段中指出要使用什么小部件(使用formfield_overrides
@admin.register(YourModel)
class YourModelAdmin(admin.ModelAdmin):
    formfield_overrides = {models.DateField: {"widget": CustomDatePickerInput}}

完成后,您将在Django管理员中拥有一个用于日期的自定义小部件。请记住,这只是一个指南,您可以通过阅读我指出的两个教程来进一步了解。

注意:该小部件的实现还支持国际化。