开始Django之旅-part7_自定义Django的管理页面

上一篇:开始Django之旅-part6_静态文件

前言

这篇文正主要关注自定义Django的自动生成的管理员页面,在第二篇文章就涉及了一点。

这篇文章是该系列的最后一篇文章,最适合于新手来初次了解Django的全貌,但是对于您开发项目来说,了解的细节太少了。所以,在下决定,这篇文章结束之后,我们再开三个系列的模块:关于Django的model的一切、关于Django的view的一切、关于Django的templates的一切。这三个模板是开发项目的重中之重,我们前期学习就先把这三个模板的细节了解通透,然后再关注Django的测试、app的复用、migrations、Django的缓存框架等等。

自定义管理员的表单

通过使用admin.site.regiser(Question)注册Question模型,Django可能会创建一个默认的表格。通常情况下,你会想要自定义admin表格的样式和工作方式。当你注册对象的时候,你可以告诉Django你想要的操作,就可以了。

让我们重新编辑表单的顺序看一下它是如何工作的,编辑polls/admin.py:

from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

你会遵循这样的模式——创建一个admin模型类,然后将其作为第二个参数传给admin.site.register()——任何时候你需要去更改admin选项的时候都可以使用。

上面特别的改变就是让“Publication date”放到“Question”字段前面
在这里插入图片描述这并不会很有印象,但是对于包含几十个字段的管理员表单来说,选择一个直觉的顺序是重要的细节。

说到几十个字段的表单,你可能会把表单划分为几个字段集合:

from django.contrib import admin

from .models import Question


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]

admin.site.register(Question, QuestionAdmin)

打开网址http://127.0.0.1:8000/admin/polls/question/查看一下效果。
在这里插入图片描述

添加相关的对象

我们现在有了Question管理页面,但是一个问题包含了多个选项,但是管理页面并没有实现选项。

有两个方法解决这个问题。第一个方法是像刚才那样去注册Choice对象:

from django.contrib import admin
from .models import Choice, Question
# ...
admin.site.register(Choice)

现在“Choices”对象就显示在管理界面上了。
在这里插入图片描述在表单上,“Question”字段是一个包含了任何问题的选择框。Django知道外键应该作为一个选择框在admin界面表示出来。

注意“Question”旁边的“添加另一个”链接。每一个带着外键关系的对象都会有一个这样的按钮。当你点击“Add another”,你就会打开一个“Add question”的弹窗表单。如果你在该窗口添加一个问题,点击保存。Django就会保存这个问题到数据库中,然后作为一个选中的选项显示在选择框内。

但是,这地狱添加Choice对象来说是没有效率的。如果当你创建一个Question对象是,就能直接添加许多Choices对象,就好了。让我们试一下吧。

移除Choice模型的register()调用。然后,编辑Question注册代码:

from django.contrib import admin

from .models import Choice, Question


class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3


class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
    ]
    inlines = [ChoiceInline]

admin.site.register(Question, QuestionAdmin)

这就告诉了Django:“Choice对象在Question管理页面可以编辑。默认的,提供3个Choices空间。”

加载“Add question”页面,看一下什么样子:

在这里插入图片描述这里有三块地方用来创建Choice对象——因为extra具体了数量——每当你返回到了已经创建的Question对象的“Change”页面是,会有另外三块地方用来创建Choice对象。

左下角有一个“Add another Choice”链接。如果你点击了它,就会添加一个新的块。如果你想要移除它们,你可以点击块右上角的X。注意,你不能移除最初的三个块。添加一个块的样子是这样:
在这里插入图片描述有一个小问题,想一下。它使用了大量的空间显示了Choice对象的所有字段。所以,Django提供了一个表格形式去显示对象。尝试一下:

polls/admin.py:

class ChoiceInline(admin.TabularInline):
    #...

使用TabularInline代替了StackeInline,相应的对象就被显示在一个紧凑的、表格的表单上。

在这里插入图片描述注意,这里有一个“Delete”的列,它可以移除已经保存的一行数据。

自定义管理员修改列表

现在,Question管理页面看起来比较不错了,让我们在“change list”上做一些修改——显示系统中所有的问题对象。

在这里插入图片描述默认情况下,Django显示每个对象中str()函数返回的内容。我们也可以显示一些独特的字段。在admin选项中使用list_display,就是字段名字的元组,像列一样显示。

polls/admin.py:

class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date')

还可以包含第二篇中的was_published_rencently()方法。

class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date', 'was_published_recently')

现在,页面就是这样子:
在这里插入图片描述你可以点击列头给他们排序——除了was_published_recently头,因为不支持按照任意方法的输出排序。同时,默认情况下,列名就是它的方法名(下划线换成了空格),每行包含了方法输出的内容。

你可以给该方法一些属性,例如:

class Question(models.Model):
    # ...
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

就可以看到:
在这里插入图片描述想要了解更多信息:list_display

再次编辑polls/admin.py文件,使用list_filter添加一个过滤器:

list_filter = ['pub_date']

它在页面的右边添加了一个“filter”:
在这里插入图片描述过滤器类型根据你设置的字段类型显示。因为pub_date是一个DateTimeFiled,Django知到给出合适的过去选项“任何时间”、“今天”、“过去7天”、“本月”、“本年”。

现在,让我们添加一个搜索功能:

search_fields = ['question_text']

这样就会在列表的顶部添加一个搜索框。当某人键入搜索词条,Django就会搜索question_text字段。你可以使用更多的字段——因为背后它用的就是一个like查询,限制搜索字段的数据到一个合理的数值,会使得你的数据库更容易查询。

现在,根据页码改变列表。默认每页显示100条数据。想看更多:修改列表的页码
搜索框
过滤器
数据层级
列头顺序

自定义管理员样式

确定的是,在每个管理页面顶部都有一个“Django administrator”,看起来有点搞笑。它其实就是个占位符。

你可以使用Django的模板系统修改它。Django的管理页面由Django自己驱动。它的接口使用Django自己的模板系统。

自定义项目的模板

在你的项目目录中创建一个templates目录(就是包含manage.py的目录)。模板可以放在Django可以访问的任何地方。

打开你的设置文件(mysiste/setting.py)添加一个Dirs选项:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

DIRS是一个文件系统目录的列表,当加载Django模板的时候就会检查,它是一个搜索路径。

组织的模板:就像静态文件一眼个,我们可以将所有的模板组合到一个大的模板目录里,它也会工作的很好。然而,属于某个特定app的模板应该放在该app的模板目录下,而不是项目的模板目录下。我们会在这里讨论更多的细节,为什么这样做:重用app指导

我们我们在templates中创建一个admin目录,然后在Django源码中(django/contrib/admin/templates)默认的Django admin模板目录中复制admin/base_site.html到这个目录。

Django源码文件在哪里呢? 如果你找源码文件比较困难,可以运行下面的命令:

...\> py -c "import django; print(django.__path__)"

然后,修改{{ site_header|default:_(‘Django administration’) }} 为你自己的地址名字:

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

我们使用这种方法将你如何重载模板。在实际的项目中,你可能使用 django.contrib.admin.AdminSite.site_header属性更容易自定义。

这个模板文件包含了大量的文本,像{% block branding %}, {{ title }}。{%和{{标签是Django模板语言的一部分。当Django渲染admin/base_site.html时,模板语言就会被赋值,生成最终的html页面。

注意,任何Django默认的管理页面都可以被重载。就像重载base_site.html页面一样。

自定义app的模板

狡猾的渲染器会问:如果DIRS默认是空的话,那么Django是如何查找默认的admin模板呢?答案就是,因为APP_DIRS设置为了True,Django自动的在每一个app包下寻找templates/子目录(不要忘记django.contrib.admin也是一个app)。

我们的投票app不是非常的复杂,不需要自定义admin模板。但是,如果它变得更加的精细,需要修改Django标准管理模板,修改app的模板更加明智,而不是修改项目中的模板。这样说的话,你可以包含投票app在任何新项目中,确保可以找到它所需要的自定义模板。

关于Django如何找到它自己的模板的更多信息。

自定义管理员index页面

同样地,你可能像要自定义Django管理index页面的样式。

默认情况下,它会按照字母顺序显示所有在admin app注册过的且存在于INSTALLED_APPS中的app。你可能修改一下你的布局,总之,index是admin中最重要的页面,它应该容易使用。

像之前那样,自定义admin/index.html页面。编辑该文件,你就会看到它使用一个叫做app_list的模板变量。这个变量包含了Django中安装过的每一个app。你可以给它们一个固定的链接,连接到你认为合适的地方。

下一步

到这里,本系列就结束了。但是别忘了,之后的三个新系列。

上一篇:开始Django之旅-part6_静态文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值