Xadmin和Ueditor
xadmin的安装
xadmin依赖
six future httplib2 django-reversion django-formtools django-crispy-forms django-import-export
方法一:
命令行模式下:
pip install xadmin
方法二:
django2.0的安装(源码安装方式):
https://github.com/sshwsfc/xadmin/tree/django2
README.rst这个文件的编码有问题,可以内容没什么重要的,可以直接到github上下载安装包,然后新建一个txt空文件,把文件名改成README.rst,替换原来的文件。替换成功后,把压缩包放到文件夹(C:Users18845EnvsxinyuonlineScripts)中,在命令窗口中进入存放压缩包的文件下,执行pip命令
(Env) C:\Users\18845\Envs\xinyuonline\Scripts>pip install xadmin-master.zip
如果上面安装提示Runtime错误:
更换安装源(使用豆瓣源)
pip install -i https://pypi.douban.com/simple xadmin-django2
安装成功后,同时也安装了很多依赖的包。
xadmin的配置
(1)新建Python Package "extra_apps",把源码xadmin文件夹放到extra_apps文件夹下面。
(2)把extra_apps右键mark为Source Root并在settings中加入
sys.path.insert(0,os.path.join(BASE_DIR, 'extra_apps'))
(3)因为我们用源码的xadmin,所以要卸载之前安装的。也可以一开始不安装xadmin,直接安装依赖包,把源文件拉到项目中。
pip uninstall xadmin
(4)配置路由
把admin改成xadmin
# urls.py from django.urls import path import xadmin urlpatterns = [ path('xadmin/', xadmin.site.urls), ]
(5)注册app
把下面两个app注册到settings.py的INSTALLED_APPS中
'xadmin', 'crispy_forms'
(6)重新生成数据库
python manage.py makemigrations python manage.py migrate
(7)设置成中文
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False #设置为本地时区
(8)创建一个管理员用户
python manage.py createsuperuser
现在就可以运行了
python manage.py runserver
访问后台:http://127.0.0.1:8000/xadmin
可以看到成功进入管理界面
app的注册
四个app下面都新建文件adminx.py,然后分别注册到后台.
UserProfile继承User因此自动注册到xadmin.
(1)users/adminx.py
# users/adminx.py import xadmin from .models import EmailVerifyRecord #xadmin中这里是继承object,不再是继承admin class EmailVerifyRecordAdmin(object): pass xadmin.site.register(EmailVerifyRecord,EmailVerifyRecordAdmin)
完善功能,增加显示字段,搜索和过滤
# users/adminx.py import xadmin from .models import EmailVerifyRecord #xadmin中这里是继承object,不再是继承admin class EmailVerifyRecordAdmin(object): # 显示的列 list_display = ['code', 'email', 'send_type', 'send_time'] # 搜索的字段,不要添加时间搜索 search_fields = ['code', 'email', 'send_type'] # 过滤 list_filter = ['code', 'email', 'send_type', 'send_time'] #每页显示多少数据 list_per_page = 3 #属性的先后顺序 fields = ['',''] #属性分组 fieldsets = [ ('base',{'fields':['','']}), ('more',{'fields':['','']}), ] #fields和fieldsets只能有一个 xadmin.site.register(EmailVerifyRecord,EmailVerifyRecordAdmin)
xadmin的全局配置
将全局配置修改:
- 如左上角:django Xadmin。下面的我的公司
- 主题修改,app名称汉化,菜单收叠。
使用Xadmin的主题功能。
把全站的配置放在usersadminx.py中:
(1)添加主题功能
添加主题后,可以选择自己喜欢的主题
from xadmin import views # 创建xadmin的最基本管理器配置,并与view绑定 class BaseSetting(object): # 开启主题功能 enable_themes = True use_bootswatch = True # 将基本配置管理与view绑定 xadmin.site.register(views.BaseAdminView,BaseSetting)
(2)全局配置
修改django admin 和下面的我的公司收起菜单
# 全局修改,固定写法 class GlobalSettings(object): # 修改title site_title = 'NBA后台管理界面' # 修改footer site_footer = '科比的公司' # 收起菜单,只显示app名,具体表名隐藏 menu_style = 'accordion' # 图标 # 将title和footer信息进行注册 # CommAdminView源码中有配置,下面 # global_search_models 全局搜索model # global_models_icon = {} 全局设置model图标 # default_model_icon = None 默认图标 # apps_label_title = {} app名字 # apps_icons = {} app图标 xadmin.site.register(views.CommAdminView,GlobalSettings)
(3)app名字改为中文
# users/apps.py from django.apps import AppConfig class UsersConfig(AppConfig): name = 'users' #app名字后台显示中文 verbose_name = "用户管理"
还需要__init__.py中修改默认配置才生效
# users/__init__.py default_app_config = 'users.apps.UsersConfig'
或者修改setting中app名称为补全名称
'users.apps.UsersConfig', 'goods.apps.GoodsConfig', 'trade.apps.TradeConfig', 'user_operation.apps.UserOperationConfig',
然后在apps中添加
from django.apps import AppConfig class UsersConfig(AppConfig): name = 'users' verbose_name = "用户管理"
或者 apps_label_title = {}这里设置名字
xadmin进阶开发
权限管理
(1)用户权限
超级用户拥有所有权限,其它添加的用户默认没有任何权限,为其添加权限
2)组的权限
添加一个组“编辑部门”,赋予权限 ,把用户加入这个组,则这个用户拥有和组相同的权限
自定义icon、默认排序、只读字段和不显示的字段
xadmin的图标采用的是第三方css样式“font awesome”,我们可以进官网下载最新的样式替代原本的,下载地址:http://www.fontawesome.com.cn/
下载完后把里面的“css”和“fonts”两个文件夹拷贝到xadmin的源码(路径:xadmin/static/vendor/font-awesome)里面
# Course的admin管理器 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'] #过滤 model_icon = 'fa fa-book' #图标 ordering = ['-click_nums'] #排序 readonly_fields = ['click_nums'] #只读字段,不能编辑 exclude = ['fav_nums'] #不显示的字段 ,和readonly_fields是冲突的 # 执行动作的位置 actions_on_bottom = True actions_on_top = True
下拉框搜索:
relfield_style = 'fk-ajax'
当有外键指向他,会以ajax方式加载
数据量过大时很有用
inlines添加数据
目前在添加课程的时候没法添加章节和课程资源,我们可以用inlines去实现这一功能
没法完成在章节中再嵌套视频
但是可以有多个inline。在添加课程时添加课程资源
course/adminx.py
class LessonInline(object): model = Lesson #extra表示创建课程时创建的章节数量 extra = 1 #style='tab'表示横向显示? style = 'tab' class CourseResourceInline(object): model = CourseResource extra = 1 #在CourseAdmin中使用inlines添加上面两个的方法 class CourseAdmin(object): inlines = [LessonInline,CourseResourceInline] #增加章节和课程资源
一张表分两个Model来管理
课程里面分为轮播课程和不是轮播课程两种类型,我们可以分开来管理
在course/models.py里面新建一个Model
class BannerCourse(Course): '''显示轮播课程''' class Meta: verbose_name = '轮播课程' verbose_name_plural = verbose_name #这里必须设置proxy=True,这样就不会再生成一张表,同时还具有Model的功能 proxy = True
course/adminx.py中重载queryset方法。
from .models import BannerCourse class CourseAdmin(object): '''课程''' list_display = [ 'name','desc','detail','degree','learn_times','students'] #显示的字段 ...... def queryset(self): # 重载queryset方法,来过滤出我们想要的数据的 qs = super(CourseAdmin, self).queryset() # 只显示is_banner=True的课程 qs = qs.filter(is_banner=False) return qs class BannerCourseAdmin(object): '''轮播课程''' list_display = [ 'name','desc','detail','degree','learn_times','students'] ...... def queryset(self): #重载queryset方法,来过滤出我们想要的数据的 qs = super(BannerCourseAdmin, self).queryset() #只显示is_banner=True的课程 qs = qs.filter(is_banner=True) return qs # 将管理器与model进行注册关联 xadmin.site.register(Course, CourseAdmin) xadmin.site.register(BannerCourse, BannerCourseAdmin)
xadmin的其它常见功能
(1)list_editable
在列表页可以直接编辑的,而不用点进去编辑。
class CourseAdmin(object): list_editable = ['degree','desc']
(2)自定义函数作为列显示
course/models.py中
class Course(models.Model): ' ' ' def get_zj_nums(self): #获取课程的章节数 return self.lesson_set.all().count() get_zj_nums.short_description = '章节数' #在后台显示的名称
course/adminx.py中
class CourseAdmin(object): list_display = ['get_zj_nums'] #直接使用函数名作为字段显示 #布尔值、下拉框的字段也可以定义一个函数,把函数名作为字段显示,比如 性别,这里的机构类别啊等等。 def sex(self): if self.sex: return '男' else: return '女' sex.short_description = '性别' #函数命名为汉字 list_display = [sex,]
效果:列表字段多了个“章节数”
(3)显示自定义的html代码
course/models.py中
class Course(models.Model): . . . def go_to(self): from django.utils.safestring import mark_safe #mark_safe后就不会转义 return mark_safe("<a href='https://home.cnblogs.com/u/derek1184405959/'>跳转</a>") go_to.short_description = "跳转"
class CourseAdmin(object): list_display = ['go_to']
效果:多了一个列表“跳转”,点击后跳转到上面定义的地址
(4)refresh定时刷新工具
course/adminx.py中
class CourseAdmin(object): refresh_times = [3,5] #自动刷新(里面是秒数)
后台效果:
可以选择3s或者5s自动刷新页面
(5)字段联动
应用场景:当添加一门课程的时候,希望课程机构里面的课程数 +1
重写xadmin的save_models方法
class CourseAdmin(object): . . . def save_models(self): # 在保存课程的时候统计课程机构的课程数 # obj实际是一个course对象 obj = self.new_obj # 如果这里不保存,新增课程,统计的课程数会少一个 obj.save() # 确定课程的课程机构存在。 if obj.course_org is not None: #找到添加的课程的课程机构 course_org = obj.course_org #课程机构的课程数量等于添加课程后的数量 course_org.course_nums = Course.objects.filter(course_org=course_org).count() course_org.save()
富文本编辑器Ueditor
(1)下载
地址:https://github.com/twz915/Dja...
解压后,把DjangoUeditor文件夹拷贝到项目目录下面
注意:直接pip install DjangoUeditor的方法会出问题
(2)settings中添加app
INSTALLED_APPS = [ 'DjangoUeditor', ]
(3)MxOnline/urls.py
# 富文本编辑器url path('ueditor/',include('DjangoUeditor.urls' )),
(4)course/models.py中Course修改detail字段
from DjangoUeditor .models import UEditorField class Course(models.Model): # detail = models.TextField("课程详情") detail = UEditorField(verbose_name=u'课程详情', width=600, height=300, imagePath="courses/ueditor/", filePath="courses/ueditor/", default='')
(5)xadmin/plugins目录下新建ueditor.py文件,代码如下
import xadmin from xadmin.views import BaseAdminPlugin, CreateAdminView, ModelFormAdminView, UpdateAdminView from DjangoUeditor.models import UEditorField from DjangoUeditor.widgets import UEditorWidget from django.conf import settings class XadminUEditorWidget(UEditorWidget): def __init__(self, **kwargs): self.ueditor_options = kwargs self.Media.js = None super(XadminUEditorWidget,self).__init__(kwargs) class UeditorPlugin(BaseAdminPlugin): def get_field_style(self, attrs, db_field, style, **kwargs): if style == 'ueditor': if isinstance(db_field, UEditorField): widget = db_field.formfield().widget param = {} param.update(widget.ueditor_settings) param.update(widget.attrs) return {'widget':XadminUEditorWidget(**param)} return attrs def block_extrahead(self, context, nodes): js = '<script type="text/javascript" src="%s"></script>' %(settings.STATIC_URL + "ueditor/ueditor.config.js") js += '<script type="text/javascript" src="%s"></script>' %(settings.STATIC_URL + "ueditor/ueditor.all.min.js") nodes.append(js) xadmin.site.register_plugin(UeditorPlugin, UpdateAdminView) xadmin.site.register_plugin(UeditorPlugin, CreateAdminView)
(6)xadmin/plugs/__init__.py里面添加ueditor插件
PLUGINS = ( 'ueditor', )
(7)course/adminx.py中使用
class CourseAdmin(object): #detail就是要显示为富文本的字段名 style_fields = {"detail": "ueditor"}
(8)course-detail.html
在模板中必须关闭Django的自动转义才能正常显示
<div class="tab_cont tab_cont1"> {% autoescape off %} {{ course.detail }} {% endautoescape %} </div>
导入excel
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'] inlines = [LessonInline] style_fields = {"detail":"ueditor"} import_excel = True def queryset(self): return super().queryset().filter(is_banner=False) def post(self, request, *args, **kwargs): # 导入逻辑 if 'excel' in request.FILES: pass return super(CourseAdmin, self).post(request, args, kwargs)