第五章 通过xadmin快速搭建后台管理系统
1、Django amdin介绍
后台管理系统的特点:
- 权限管理
- 少前段样式
- 快速开发
xadmin是Django中的一个杀手级后台管理系统
xadmin是Django自带的,在新建项目时就已经存在的。打开settings.py文件就可以看到Installed_apps中有django.contrb.admin一项。
Installed_apps:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'courses',
'organization',
'operation'
]
运行项目时,输入http://127.0.0.1:8000/admin,就可以访问默认的后台管理系统
此时回到pycharm中运行manage.py,创建超级用户。
manage.py@MxOnline > createsuperuser
bash -cl "/home/liang/.virtualenvs/mxonline/bin/python2.7 /home/liang/pycharm-2017.2.4/helpers/pycharm/django_manage.py createsuperuser /home/liang/PycharmProjects/MxOnline"
Username: liang
Email address: myliangchengyu@163.com
Warning: Password input may be echoed.
Password: admin123
Warning: Password input may be echoed.
Password (again): admin123
Superuser created successfully.
Process finished with exit code 0
再次运行项目,登录http://127.0.0.1:8000/admin/
显示登陆成功,界面语言为英语,可在settings.py文件中更改语言。
LANGUAGE_CODE = 'zh-hans'
需要注意的是,在Django1.7版本之前,中文的编码是叫做”zh-CN”,1.8版本之后为”zh-hans”。
时区改为上海
TIME_ZONE = 'UTC'
将Django的时间由国际时间改为本地时间,USE_TZ改为False:
USE_TZ = True
Django为我们自动注册了组,这个组就对应后台数据库auth_group,可以将任何的models都注册进去,然后对这些表任意的增删改查。
users app目录下有admin.py文件,它就是用来注册后台管理系统的,在startapp后自动生成好的。
在此文件中,将users.UserProfile注册进来。
#_*_ encoding:utf-8 _*_
from django.contrib import admin
# Register your models here.
from .models import UserProfile #当前目录下的models直接用.就可以
class UserProfileAdmin(admin.ModelAdmin):
pass
admin.site.register(UserProfile, UserProfileAdmin)
此时,重新访问后台系统,多出了用户表,此时点击增加即可增加记录
2、xadmin的安装
xadmin是基于Django自带的admin,比admin更强大的一套后台管理系统,本项目都是采用xadmin后天管理系统完成的。
通过pip命令安装:
liang@l:~$ workon mxonline
(mxonline) liang@l:~$ pip install xadmin
Collecting xadmin
Downloading xadmin-0.6.1.tar.gz (1.0MB)
100% |████████████████████████████████| 1.0MB 192kB/s
Requirement already satisfied: setuptools in ./.virtualenvs/mxonline/lib/python2.7/site-packages (from xadmin)
Requirement already satisfied: django<2.0.0,>=1.9.0 in ./.virtualenvs/mxonline/lib/python2.7/site-packages (from xadmin)
Collecting django-crispy-forms>=1.6.0 (from xadmin)
Downloading django_crispy_forms-1.7.0-py2.py3-none-any.whl (104kB)
100% |████████████████████████████████| 112kB 224kB/s
Collecting django-formtools>=1.0 (from xadmin)
Downloading django_formtools-2.1-py2.py3-none-any.whl (132kB)
100% |████████████████████████████████| 133kB 192kB/s
Collecting httplib2==0.9.2 (from xadmin)
Downloading httplib2-0.9.2.zip (210kB)
100% |████████████████████████████████| 215kB 208kB/s
Building wheels for collected packages: xadmin, httplib2
Running setup.py bdist_wheel for xadmin ... done
Stored in directory: /home/liang/.cache/pip/wheels/cb/fa/55/706b155c6a746d623d82ad38b4d31e8f2f58729f710d84d102
Running setup.py bdist_wheel for httplib2 ... done
Stored in directory: /home/liang/.cache/pip/wheels/c7/67/60/e0be8ccfc1e08f8ff1f50d99ea5378e204580ea77b0169fb55
Successfully built xadmin httplib2
Installing collected packages: django-crispy-forms, django-formtools, httplib2, xadmin
Successfully installed django-crispy-forms-1.7.0 django-formtools-2.1 httplib2-0.9.2 xadmin-0.6.1
在settings.py文件中,注册xadmin和crispy-forms两个app
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'courses',
'organization',
'operation',
'xadmin',
'crispy_forms' #注意是下划线
]
把默认的admin指向xadmin的URL,这样就完成了xadmin的替换。
替换前:
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
替换后:
from django.conf.urls import url
from django.contrib import admin
import xadmin
urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
]
此时运行项目,访问 http://127.0.0.1:8000/xadmin/ ,提示”Table ‘mxonline.xadmin_usersettings’ doesn’t exist”
因为xadmin存在很多默认的表,在xadmin安装完成之后,还要把xadmin的表给同步过来
用miagrations和migrate命令更新数据库
manage.py@MxOnline > migrate
bash -cl "/home/liang/.virtualenvs/mxonline/bin/python2.7 /home/liang/pycharm-2017.2.4/helpers/pycharm/django_manage.py migrate /home/liang/PycharmProjects/MxOnline"
Operations to perform:
Apply all migrations: xadmin, users, sessions, admin, auth, courses, contenttypes, organization, operation
Running migrations:
Rendering model states... DONE
Applying xadmin.0001_initial... OK
Process finished with exit code 0
此时数据库中将会多出三个表
此时再刷新页面,出现一个全新的后台界面
进入xadmin官网,可以看到xadmin的各种特性
xadmin安装的另一种方法:在github上下载xadmin的原码,便于日后修改,另外,很多xadmin的新功能在还没有发布到pypi上面的时候,就可以直接用原码体现它的新特性。
将解压出的xadmin文件夹
拷贝到项目的根目录下
再新建一个extra_app文件夹用于存放第三方app,把xadmin给拖进去,并mark成source root。
==同时修改settings.py文件注册根目录,否则运行manage.py文件时会报错:==
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,os.path.join(BASE_DIR,'apps'))
sys.path.insert(0,os.path.join(BASE_DIR,'extra_apps'))
由于直接import会优先导入环境中的xadmin包,所以先要将环境中的xadmin卸载掉:
(mxonline) liang@l:~$ pip uninstall xadmin
再参考 https://github.com/sshwsfc/xadmin/blob/master/requirements.txt 网址中,把缺少的依赖包都安装好。
(mxonline) liang@l:~$ pip install future six httplib2
再安装另一个工具
(mxonline) liang@l:~$ pip install django-import-export
再度运行,成功运行。
3、users app的model注册
先对pycharm进行一项设置,可以在新建×.py文件时自动填充模板内容:
在users根目录下新建一个adminx.py文件,编写以将邮箱验证码注册到xadmin管理系统中:
import xadmin
from .models import EmailVerifyRecord
class EmailVeriflyRecordAdmin(object):
pass
xadmin.site.register(EmailVerifyRecord, EmailVeriflyRecordAdmin)
再次访问xadmin界面:
该项注册成功
添加一条项目时,会报错ProgrammingError at /xadmin/users/emailverifyrecord/add/,(1146, “Table ‘mxonline.xadmin_log’ doesn’t exist”),这是因为数据库还使用上个版本的xadmin生成的数据表,此时要重新migrations xadmin:
manage.py@MxOnline > migrate xadmin
bash -cl "/home/liang/.virtualenvs/mxonline/bin/python2.7 /home/liang/pycharm-2017.2.4/helpers/pycharm/django_manage.py migrate xadmin /home/liang/PycharmProjects/MxOnline"
Operations to perform:
Apply all migrations: xadmin
Running migrations:
Rendering model states... DONE
Applying xadmin.0002_log... OK
Applying xadmin.0003_auto_20160715_0100... OK
Process finished with exit code 0
在models.py文件中,加入最后一个重载的Unicode方法,可以决定邮箱验证码列表中是如何显示的。
class EmailVerifyRecord(models.Model):
code = models.CharField(max_length=20, verbose_name=u"验证码")
email = models.EmailField(max_length=50, verbose_name=u"邮箱")
send_type = models.CharField(verbose_name=u"验证码类型",choices=(("register",u"注册"),("forget",u"找回密码")),max_length=10)
send_time = models.DateTimeField(verbose_name=u"发送时间",default=datetime.now)
#now加括号的话会生成实际编译的时间,不加括号的话生成类实例化的时间
class Meta:
verbose_name = u"邮箱验证码"
verbose_name_plural = verbose_name
def __unicode__(self):
return '{0}({1})'.format(self.code, self.email) #列表的显示内容
在xadmin.py文件中定义需要展示哪些列:
class EmailVeriflyRecordAdmin(object):
list_display = ['code','email','send_type','send_time']
展示界面即发生改变:
在增加一个搜索框:
class EmailVeriflyRecordAdmin(object):
list_display = ['code','email','send_type','send_time']
search_fields = ['code','email','send_type']
原界面就会发生了改变:
变得可以搜索:
再增加一个筛选字段:
class EmailVeriflyRecordAdmin(object):
list_display = ['code','email','send_type','send_time']
search_fields = ['code','email','send_type']
list_filter = ['code','email','send_type','send_time']
会出现一个筛选工具:
用同样的方法,注册Banner,新建类并关联:
class BannerAadmin(object):
list_display = ['title', 'image', 'url', 'index','add_time']
search_fields = ['title', 'image', 'url', 'index']
list_filter = ['title', 'image', 'url', 'index','add_time']
xadmin.site.register(Banner, BannerAadmin)
4、剩余apps models注册
依据同样的方法编辑如下文件:
courses/adminx.py文件:
# -*-coding:utf-8 -*-
__author__ = 'liang'
__date__ = '17-12-4 下午9:43'
import xadmin
from .models import Course, Lesson, Video, CourseResource
class CourseAdmin(object):
list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']
search_fields = ['name', 'desc', 'detail', 'degree', 'students']
list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']
class LessonAdmin(object):
list_display = ['course', 'name', 'add_time']
search_fields = ['course', 'name']
list_filter = ['course__name', 'name', 'add_time'] #外键的name字段
class VideoAdmin(object):
list_display = ['lesson', 'name', 'add_time']
search_fields = ['lesson', 'name']
list_filter = ['lesson', 'name', 'add_time']
model_icon = 'fa fa-film'
class CourseResourceAdmin(object):
list_display = ['course', 'name', 'download', 'add_time']
search_fields = ['course', 'name', 'download']
list_filter = ['course', 'name', 'download', 'add_time']
xadmin.site.register(Course, CourseAdmin)
xadmin.site.register(Lesson, LessonAdmin)
xadmin.site.register(Video, VideoAdmin)
xadmin.site.register(CourseResource, CourseResourceAdmin)
organization/adminx.py文件:
# -*-coding:utf-8 -*-
__author__ = 'liang'
__date__ = '17-12-4 下午10:08'
import xadmin
from .models import CityDict, CourseOrg, Teacher
class CityDictAdmin(object):
list_display = ['name', 'desc', 'add_time']
search_fields = ['name', 'desc']
list_filter = ['name', 'desc', 'add_time']
class CourseOrgAdmin(object):
list_display = ['name', 'desc', 'click_nums', 'fav_nums']
search_fields = ['name', 'desc', 'click_nums', 'fav_nums']
list_filter = ['name', 'desc', 'click_nums', 'fav_nums']
relfield_style = 'fk-ajax'
style_fields = {"desc":"ueditor"}
class TeacherAdmin(object):
list_display = ['org', 'name', 'work_years', 'work_company']
search_fields = ['org', 'name', 'work_years', 'work_company']
list_filter = ['org', 'name', 'work_years', 'work_company']
xadmin.site.register(CityDict, CityDictAdmin)
xadmin.site.register(CourseOrg, CourseOrgAdmin)
xadmin.site.register(Teacher, TeacherAdmin)
operation/adminx.py文件:
# -*-coding:utf-8 -*-
__author__ = 'liang'
__date__ = '17-12-4 下午10:08'
import xadmin
from .models import CityDict, CourseOrg, Teacher
class CityDictAdmin(object):
list_display = ['name', 'desc', 'add_time']
search_fields = ['name', 'desc']
list_filter = ['name', 'desc', 'add_time']
class CourseOrgAdmin(object):
list_display = ['name', 'desc', 'click_nums', 'fav_nums']
search_fields = ['name', 'desc', 'click_nums', 'fav_nums']
list_filter = ['name', 'desc', 'click_nums', 'fav_nums']
relfield_style = 'fk-ajax'
style_fields = {"desc":"ueditor"}
class TeacherAdmin(object):
list_display = ['org', 'name', 'work_years', 'work_company']
search_fields = ['org', 'name', 'work_years', 'work_company']
list_filter = ['org', 'name', 'work_years', 'work_company']
xadmin.site.register(CityDict, CityDictAdmin)
xadmin.site.register(CourseOrg, CourseOrgAdmin)
xadmin.site.register(Teacher, TeacherAdmin)
需要注意的是,作为外键,被其他类访问时,不会显示类的内容,只会显示成object,此时,可以用重载unicode方法,使返回类的某个字段名即可:
def __unicode__(self):
return self.name
同样,引用时,==利用双下划线引用类的某个字段==,如:
list_filter = ['course__name', 'name', 'add_time'] #外键的name字段
5、xadmin全局配置
xadmin中包含更换主题的功能,首先,激活xadmin的主题功能,将如下代码加入users/adminx.py文件中:
from xadmin import views
class BaseSetting(object):
enable_themes = True #主体功能
use_bootwatch = True
xadmin.site.register(views.BaseAdminView, BaseSetting)
此时,右上角增加主题按钮:
因为后期主题下载网站请求模式变化了,参考 http://blog.csdn.net/dimples_54/article/details/77963593 文章进行修改,运行后可以切换主题
再在users/adminx.py文件中加入:
class GlobalSettings(object):
site_title = "慕学后台管理系统"
site_footer = "慕学在线网"
xadmin.site.register(views.CommAdminView, GlobalSettings)
网站标题发生了改变:
脚注也发生了改变:
再在GlobalSettings类中加入一个参数:
class GlobalSettings(object):
site_title = "慕学后台管理系统"
site_footer = "慕学在线网"
menu_style = "accordion"
此时左侧的apps都默认收起,点开展示:
为了让列表里的apps也显示中文名,修改apps/users/apps.py文件
# -*-coding:utf-8 -*-
from django.apps import AppConfig
class OperationConfig(AppConfig):
name = 'operation'
verbose_name = u"用户操作"
并在apps/users/_ init _.py文件:
default_app_config = "users.apps.UsersConfig"
同理,修改apps/courses/apps.py
#_*_ encoding:utf-8 _*_
from django.apps import AppConfig
class CoursesConfig(AppConfig):
name = 'courses'
verbose_name = u"课程管理"
并修改apps/courses/_ init _.py文件:
default_app_config = "courses.apps.CoursesConfig"
修改apps/operation/apps.py
# -*-coding:utf-8 -*-
from django.apps import AppConfig
class OperationConfig(AppConfig):
name = 'operation'
verbose_name = u"用户操作"
并修改apps/operation/_ init _.py文件:
default_app_config = "operation.apps.OperationConfig"
修改apps/organization/apps.py
#_*_ encoding:utf-8 _*_
from django.apps import AppConfig
class OrganizationConfig(AppConfig):
name = 'organization'
verbose_name = u"机构管理"
并修改apps/organization/_ init _.py文件:
default_app_config = "organization.apps.OrganizationConfig"
最终运行结果,apps的名称全部修改为中文了:
至此,全局配置,完成设置了主题、网站标题、网站脚注、对apps的名称做中文修改。