返回顶部
扩大
缩小

Zhang_derek

Django+xadmin打造在线教育平台(十)

目录

在线教育平台(一)      在线教育平台(二)

在线教育平台(三)      在线教育平台(四)

在线教育平台(五)      在线教育平台(六)

在线教育平台(七)      在线教育平台(八)

在线教育平台(九)      在线教育平台(十)

代码

github下载

教程

学习自慕课网-使用python3.x与Django2.0.1开发的在线教育平台

十四、xadmin的进阶开发

14.1.权限管理

(1)用户权限

超级用户拥有所有权限,其它添加的用户默认没有任何权限

进后台添加一个用户“Editor1”,勾上“职员状态”后,这个用户才可以登录进后台,默认没添加权限的用户登录到后台的情况如下:

接下来,为用户Editor1添加查看课程和查看章节的权限

 

 再刷新可以看到,有了查看课程和章节的权限了

 

 (2)组的权限

 添加一个组“编辑部门”,赋予如下权限 :

 把刚才的用户“Editor1”加入到“编辑部门”这个组,然后看用户现在的权限如下:

 

组里面的成员不但拥有自己本身的权限外,还会拥有组的权限

 

14.2.自定义icon

 xadmin的图标采用的是第三方css样式“font awesome”,我们可以进官网下载最新的样式替代原本的,下载地址:http://www.fontawesome.com.cn/

下载完后把里面的“css”和“fonts”两个文件夹拷贝到xadmin的源码(路径:xadmin/static/vendor/font-awesome)里面

 

使用方法:

以course为例

(1)进官网找到图标的样式

(2)course/adminx.py使用

# 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'

再在后台刷新(ctrl+F5),就可以看到图标了

 

14.3.默认排序、只读字段和不显示的字段

课程:

  • 按点击数倒序排序
  • 点击数不能编辑
  • 不显示收藏人数
# 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']               #不显示的字段

 

14.4.inlines添加数据

 目前在添加课程的时候没法添加章节和课程资源,我们可以用inlines去实现这一功能

class LessonInline(object):
    model = Lesson
    extra = 0


class CourseResourceInline(object):
    model = CourseResource
    extra = 0


#在CourseAdmin中使用inlines添加上面两个的方法
class CourseAdmin(object):
    inlines = [LessonInline,CourseResourceInline]    #增加章节和课程资源

效果如下:

再添加课程的时候,可以直接添加章节和课程资源

 

 

14.5.一张表分两个Model来管理

课程里面分为轮播课程和不是轮播课程两种类型,我们可以分开来管理

(1)在course/models.py里面新建一个Model

class BannerCourse(Course):
    '''显示轮播课程'''
    class Meta:
        verbose_name = '轮播课程'
        verbose_name_plural = verbose_name
        #这里必须设置proxy=True,这样就不会再生成一张表,同时还具有Model的功能
        proxy = True

(2)course/adminx.py

from .models import BannerCourse

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']               #不显示的字段
    inlines = [LessonInline,CourseResourceInline]    #增加章节和课程资源

    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']
    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']
    inlines = [LessonInline,CourseResourceInline]

    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)

 

后台:可以看到多了一个轮播课程,来达到分类管理的一个功能

 

 

 

14.6.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']  #直接使用函数名作为字段显示

效果:列表字段多了个“章节数”

 

(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 = "跳转"

course/adminx.py中

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()
# course/adminx.py

import xadmin

from .models import Course, Lesson, Video, CourseResource,BannerCourse
from organization.models import CourseOrg

class LessonInline(object):
    model = Lesson
    extra = 0


class CourseResourceInline(object):
    model = CourseResource
    extra = 0


# Course的admin管理器
class CourseAdmin(object):
    '''课程'''

    list_display = [ 'name','desc','detail','degree','learn_times','students','get_zj_nums','go_to']   #显示的字段
    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']               #不显示的字段
    list_editable = ['degree','desc']
    # refresh_times = [3,5]                #自动刷新(里面是秒数范围)
    inlines = [LessonInline,CourseResourceInline]    #增加章节和课程资源

    def queryset(self):
        # 重载queryset方法,来过滤出我们想要的数据的
        qs = super(CourseAdmin, self).queryset()
        # 只显示is_banner=True的课程
        qs = qs.filter(is_banner=False)
        return qs

    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()


class BannerCourseAdmin(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']
    inlines = [LessonInline,CourseResourceInline]

    def queryset(self):
        #重载queryset方法,来过滤出我们想要的数据的
        qs = super(BannerCourseAdmin, self).queryset()
        #只显示is_banner=True的课程
        qs = qs.filter(is_banner=True)
        return qs

class LessonAdmin(object):
    '''章节'''

    list_display = ['course', 'name', 'add_time']
    search_fields = ['course', 'name']
    #这里course__name是根据课程名称过滤
    list_filter = ['course__name', 'name', 'add_time']


class VideoAdmin(object):
    '''视频'''

    list_display = ['lesson', 'name', 'add_time']
    search_fields = ['lesson', 'name']
    list_filter = ['lesson', 'name', 'add_time']


class CourseResourceAdmin(object):
    '''课程资源'''

    list_display = ['course', 'name', 'download', 'add_time']
    search_fields = ['course', 'name', 'download']
    list_filter = ['course__name', 'name', 'download', 'add_time']


# 将管理器与model进行注册关联
xadmin.site.register(Course, CourseAdmin)
xadmin.site.register(BannerCourse, BannerCourseAdmin)
xadmin.site.register(Lesson, LessonAdmin)
xadmin.site.register(Video, VideoAdmin)
xadmin.site.register(CourseResource, CourseResourceAdmin)
course/adminx.py全部代码

 

14.7.增加富文本编辑器Ueditor

(1)下载

地址:https://github.com/twz915/DjangoUeditor3/

解压后,把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字段

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/plugs目录下新建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>

最终效果:

后台编辑页面

 

 前端显示

 

 

 

 

posted on 2018-03-31 17:20  zhang_derek  阅读(20014)  评论(8编辑  收藏  举报

导航