Django基础7-自定义管理站点

自定义管理员表单

通过使用admin.site.register(Question)注册了Question模型之后,Django可以构造一个默认的表单。往往,你希望自定义管理员表单的外观和工作方式。在注册模型时,你可以告诉Django你想要的选项,以达到你的自定目的。

让我们通过重排表单上的字段来看看它是如何工作的。使用如下代码,替换admin.site.register(Question):

from django.contrib import admin

from .models import Question

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

admin.site.register(Question, QuestionAdmin)

以上改变使得“Date published”在“Question Text”之前, 你可以通过改变fields列表中字段的次序,来改变UI元素的排列的先后顺序。

这只有两个控件,这并不令人印象深刻,但对于数十个控件的管理页面,选择一个直观的顺序是一个重要的可用性细节。

说到几十个控件的表格,你可能想把表格分成几个字段:

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

admin.site.register(Question, QuestionAdmin)

添加关联的对象

我们有了Question管理页面,但是一个Question有多个选项,而且管理页面没有显示选项。
有两个方法来解决这个问题。第一个方法是在admin中注册Choice,就如注册Question一样,这很简单:

from django.contrib import admin

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

但是这样操作起来非常麻烦,将问题与选项独立起来了,也不符合逻辑。我们更希望在添加问题的时候,能够直接添加选项。

移除Choice模型的注册代码,并修改代码如下:

from django.contrib import admin
from .models import Question, Choice

# Register your models here.
class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3
class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]
    inlines = [ChoiceInline]

admin.site.register(Question, QuestionAdmin)

这段代码告诉Django:Choice对象在Question管理页面进行编辑。默认提供三个选项。你可以运行一下看看效果。

还有个小问题,我们可能会希望选项的UI元素都显示在同一行。你只需要修改ChoiceInline就行了:

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

为什么会多一个“Delete?”列呢?那是因为除了默认的三个选项,你可以通过系统提供的添加按钮,添加更多选项,而这些额外的选项,将会提供一个删除按钮,出现在“Delete?”列。

自定义修改页面

默认,Django会将每个对象的str()显示出来。但是有时候,我们还想显示一些其他的我们关心的字段。为此,使用list_display 管理选项,这是一个由字段名构成的元组,作为列显示:

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

你可以点击列头来排序–除了was_published_recently之外。因为通过output of an arbitrary method排序是不支持的。还有就是,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?'

再次编辑polls/admin.py 文件, Question 修改 列表页作进一步的改进: 使用list_filter来进行数据过滤. 添加如下代码到QuestionAdmin:

class QuestionAdmin(admin.ModelAdmin):
    ...
    list_filter = ['pub_date']

filter的类型取决于你设置的过滤字段 . 因为 pub_date是一个DateTimeField字段, Django 知道 给出哪些合适的过滤选项 : “Any date”, “Today”, “Past 7 days”, “This month”, “This year”.

我们再来添加搜索功能:

class QuestionAdmin(admin.ModelAdmin):
    ...
	search_fields = ['question_text']

这将会在修改列表的顶部添加一个搜索框,并可以根据问题的文字进行搜索。你也可以设置多个搜索字段,但不宜过多。

是时候注意修改列表可以自由地分页。默认显示100个项每页。 修改列表的pagination, search boxes, filters, date-hierarchies, and column-header-ordering 协同工作,就如你所想那样。

自定义管理员界面的外观和感觉

管理员界面的很多内容是使用Django的模版系统生成的,我们必须做一些必要的修改和定制。

自定义项目模版

项目模版可以放在你的文件系统中任何Django可以访问到的地方。但是把它放在你的项目中是一个很好的约定。在你的项目目录(包含manage.py的目录)创建一个templates目录。打开设置文件(mysite/settings.py),然后在TEMPLATES设置中添加一个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模版时会检测它;它是一个搜索路径。

现在,在templates目录中创建一个admin子目录,然后,将Django默认的管理界面模版“admin/base_site.html ”(目录:django/contrib/admin/templates)拷贝到该admin目录下。

如何找到django目录?
方法1:

>>> sys.path
[...
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages']

方法2:

fwwdeair:~ fww$ python3 -c "import django;print(django.__path__)"
['/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django']

然后,编辑该文件,将 {{ 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 }}的内容. {% 和 {{ tags 是Django模版语言的内容。当Django渲染该模版文件时,模版语言会被转换为最终的HTML页面。

所有Django的默认模版都可以被覆盖。要覆盖一个模版,只需要将其从默认目录下拷贝到你自己的目录中,然后做出修改,就像你在base_site.html中所做的事情一样。

自定义应用模版

聪明的读者可能会问:如果“DIRS”是默认的空值,Django是如何寻找默认的管理模版的呢?答案是,因为”APP_DIRS“被设置为True,Django自动在每个应用包的
”templates/ subdirectory“中查找模版来使用,不要忘了,django.contrib.admin 也是一个应用。
我们的poll应用不是很复杂,并且不需要进行管理模版自定义。但是如果它变得复杂和功能强大,可能就需要修改标准的管理模版,而不是使用默认的。这样,你就可以将poll应用包含在任何项目中,但是你要确保它可以找到它所需要的自定义模版。

查看 “template loading documentation” 以获得更多关于Django 如何寻找其模版的内容。

自定义管理员索引页

同样,你可能也会想要自定义管理员索引页的外观。
默认的,它会按照字母顺序显示所有“INSTALLED_APPS”中的注册的应用。你可能想要更改其布局。毕竟,索引页是管理页面中最重要的,而且它应该易于使用。
自定义管理员索引页对应的模版是“admin/index.html”。(对它做相同的事情,就如你对admin/base_site.html所做的那样–把它从默认目录拷贝到你自己的目录)。
编辑该文件,你会看到它使用了一个模版变量叫做“app_list”。这个变量包含了每一个安装的Django应用。你可以强制连接到以对象形式描述的管理页面,来代替它。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值