Xadmin和Ueditor

JasonYeung 2019-06-28

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

Xadmin和Ueditor
(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)

相关推荐