编写你的第一个Django应用:

我们将继续开发网页投票应用,并将注意力集中于Django自动生成的管理界面上。


创建一个管理用户:

首先,我们需要创建一个能够登陆管理站点的用户,运行如下命令:

$ python manage.py createsuperuser


启动开发服务器:

Django的管理站点是默认启用的。 让我们启动开发服务器,然后探索它。

从教程1中我们了解到,你可以通过使用下面的命令来启动开发服务器:

$ python manage.py runserver


让poll应用在管理站点中可编辑:

但我们的Poll应用在哪里? 它没有显示在管理站点的首页面上:


只需要做一件事:我们需要告诉管理站点Question 对象要有一个管理界面。 要做这件事,需要打开polls/admin.py文件,把它编辑成这样:

polls/admin.py
from django.contrib import admin

from .models import Question

admin.site.register(Question)




node2:/django1.8/mysite/polls#vim admin.py
node2:/django1.8/mysite/polls#cat models.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __str__(self):              # __unicode__ on Python 2
        return self.question_text


注意事项:

1.这个表单是根据Question模型文件自动生成的



2.模型中不同类型的字段(DateTimeField、CharField)会对应的HTML输入空间,每一种类型的字段,Django管理站点都知道如何显示



界面的底部几个按钮:



自定义管理表单:

得来全不费工夫,只需使用admin.site.register(Question)注册Question模型,

Django 就能构造一个默认的表单表示。

通常,你会想要自定义管理界面中表单的外观和功能.


让我们通过编辑表单上的字段重新来看一下它是如何工作的,将admin.site.register(Question)行替换成:



你将遵循此模式--创建一个模型管理对象,然后将其作为第2个参数传递给admin.site.register() -


任何时候你需要改变对象的管理选项。

仅有两个字段不会令你印象深刻,但是当管理有许多字段的表单时,选择一个直观的排序方式是一个重要而使用的细节。

说到有许多字段的表单,你可能想把表单分割成字段集:



添加关联对象:

好了,我们已经有自己的Question管理界面,但是一个Question有多个Choices,管理界面中并没有选项显示出来


node2:/django1.8/mysite/polls#cat admin.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib import admin

# Register your models here.
from django.contrib import admin

from .models import Question,Choice
class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]
admin.site.register(Question,QuestionAdmin)
admin.site.register(Choice)


现在,可以在Django管理站点中管理“Choices”。

 “Add choice”表单看起来像这样:


mysql>  select * from polls_choice;
+----+---------------+-------+-------------+
| id | choice_text   | votes | question_id |
+----+---------------+-------+-------------+
|  1 | 5555555555555 |     6 |           1 |
|  2 | 444444444     |     0 |           1 |
+----+---------------+-------+-------------+
2 rows in set (0.00 sec)

mysql> select * from polls_question;
+----+---------------+----------------------------+
| id | question_text | pub_date                   |
+----+---------------+----------------------------+
|  1 | aaaaa         | 2017-11-20 00:15:41.000000 |
|  2 | 9999999999    | 2017-11-20 00:24:27.000000 |
|  3 | aabbccdd      | 2017-12-05 00:00:00.000000 |
|  4 | tlcb999       | 2017-11-19 16:30:46.453816 |
|  5 | 5555          | 2017-12-05 07:55:36.000000 |
+----+---------------+----------------------------+
5 rows in set (0.00 sec)



在这个表单中,"Question"字段是一个可选的选项框,包含数据库中所有的Question.Django 知道ForeignKey

应该在管理界面中显示Wie一个<select>选框。


但事实上,这不是一种添加Choice对象到系统中高效的方式,在创建Question对象的同时可以直接添加一组Chice将会更好。

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)



自定义管理界面中的变更列表




polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question_text', 'pub_date')
为了更好地评估对象,让我们将教程1中自定义的方法was_published_recently 添加进来:

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



自定义管理站点的外观:

很明显,每个管理页面顶部都有“Django administration”不太合适。它仅仅起到了占位符的作用。


它可以用Django的模板系统轻松改变,Django的管理站点是用Django自己制作出来的,它的界面代码使用的是Django自己的模板系统。


mysite/settings.py
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安装的源目录(目录为django/contrib/admin/templates)将模板页面的源文件admin/base_site.html拷贝到这个文件夹里。

Django的源文件在哪里?

如果你找不到Django源文件在你系统上的位置,运行如下命令:

node2:/django1.8/mysite/mysite#python -c "
> import sys
> sys.path = sys.path[1:]
> import django
> print(django.__path__)"
['/usr/local/python27/lib/python2.7/site-packages/django']
node2:/django1.8/mysite/mysite#




node2:/usr/local/python27/lib/python2.7/site-packages/django/contrib/admin/templates/admin#cp base_site.html /django1.8/mysite/mysite/templates/admin

node2:/django1.8/mysite#cp -r mysite/templates/ .
node2:/django1.8/mysite#ls
manage.py  mysite  polls  templates

自定义应用的模板:

细心的读者将会问:由于DIRS默认是空的


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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',
            ],
        },
    },
]