前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >零基础使用Django2.0.1打造在线教育网站(二十六):xadmin的进阶开发

零基础使用Django2.0.1打造在线教育网站(二十六):xadmin的进阶开发

原创
作者头像
啃饼思录
发布2018-09-13 21:55:08
1.3K0
发布2018-09-13 21:55:08
举报

关于博主

努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

代码语言:txt
复制
                                      微信公众号:  啃饼思录
代码语言:txt
复制
                                    QQ: 2810706745(啃饼小白)

写在前面

本篇笔记我们将介绍xadmin的进阶开发,具体包括自定义icon,默认排序,字段只读,字段隐藏,搜索框,inlines,一张表分两个model来进行管理添加数据,直接列表页编辑,列表页显示章节数,显示自定义的html代码,列表页定时刷新,字段联动功能,xadmin源码目录简说,xadmin集成富文本等功能,下面我们依次介绍一下。

本篇笔记对应于第二十六篇代码,对应于github的位置是https://github.com/licheetools/eduline

首先需要把我们在前面当Debug=False时,修改的以下代码全部删除掉:


为了解决上述问题,我们这样做:打开eduline/settings.py文件,新增代码如下:

代码语言:txt
复制
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

同时将里面的STATICFILES_DIRS给注释掉(这一步很重要,否则系统还是去找这个文件,事实上是找不到的,所以还是图片加载不出来):

代码语言:txt
复制
# STATICFILES_DIRS = [
#     os.path.join(BASE_DIR, "static"),  # 说明静态文件放在哪个目录,记住这里只能用列表或者元组,单一一个元组需要用,结尾
# ]

打开eduline/urls.py文件,新增代码如下:

代码语言:txt
复制
from eduline.settings import  STATIC_ROOT

 # 配置静态文件上传的访问处理url
    re_path('static/(?P<path>.*)', serve, {"document_root": STATIC_ROOT}),

恢复到Debug=True时的状态。

然后进入到我们的xadmin后台,开始xadmin的进阶开发。

自定义icon

所谓icon其实就是你的功能小图标:

我们以修改邮箱验证码为例,打开users/adminx.py文件,在EmailVerifyRecordAdmin函数新增一行代码:

代码语言:txt
复制
model_icon = 'fa fa-user'

其实这个样式就是对应于font awesome里面的图标,你可以下载新的源代码对你的目录下的css和fonts文件夹进行替换:

然后刷新一下就出现自己想要的样式icon了。

默认排序,字段只读,字段隐藏

我们以课程为例,来介绍这3个小功能。打开couses/adminx.py文件,在CourseAdmin中加入以下代码:

代码语言:txt
复制
# 默认排序:以点击数排序
ordering = ['-click_nums']

# 字段只读:点击数只允许读取
readonly_fields = ['click_nums', 'fav_nums']

# 字段隐藏:收藏数隐藏显示
exclude = ['fav_nums']

# 注意字段只读和字段隐藏是冲突的,不允许设置一个字段只读同时隐藏

搜索框

当课程很多时,我们不能以下拉菜单的形式来查找我们的课程,我们需要有搜索框。你已经知道,课程它有一个外键是课程机构,因此我们需要到课程机构里面进行搜索框的配置。打开organization/adminx.py文件,在CourseOrgAdmin函数里面添加一行代码:

代码语言:txt
复制
# 搜索框,当课程数据量过大时,有课程指向它,会以ajax方式加载
    relfield_style = 'fk-ajax'

inlines添加数据

在这之前,我们新增课程的时候是不能同时新增课程章节信息的,需要跳到另一个页面,这是很麻烦的。所以我们考虑采用inlines来添加数据从而完成在一个页面直接完成章节信息的添加。

打开couses/adminx.py文件,在最顶部新定义一个函数:

代码语言:txt
复制
# 课程直接添加章节
class LessonInline(object):
    model = Lesson
    extra = 0

# 同时在CourseAdmin中,新增一行代码
# 课程直接添加章节
    inlines = [LessonInline] # 数组,支持多个

刷新一下我们的后台,发现章节信息在课程页面底部出现了:

同时也支持多个添加,比方再添加一个课程资源:

一张表分两个model来进行管理

录播课程与非轮播课程可以分开管理,但是最好是在一张表里显示。打开courses/models.py文件,在course函数下面新增代码

代码语言:txt
复制
class BannerCourse(Course):  # 注意是继承Course而不是object这个最高类
    class Meta:
        verbose_name = "轮播课程"
        verbose_name_plural = verbose_name
        proxy = True  # 很重要,否则会生成另外一张表,这样设置具有model的功能,但不会生成表

然后打开courses/adminx.py文件,修改之前的代码:

代码语言:txt
复制
from .models import  BannerCourse

class CourseAdmin(object):
    list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'fav_nums', 'image', 'click_nums',
                    'add_time']  # 一次显示你想出现的多行数据
    search_fields = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'fav_nums', 'image',
                     'click_nums']  # 查询你想要的数据
    list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'fav_nums', 'image', 'click_nums',
                   'add_time']  # 过滤器
    # # 默认排序:以点击数排序
    # ordering = ['-click_nums']
    #
    # # 字段只读:点击数只允许读取
    # readonly_fields = ['click_nums', 'fav_nums']
    #
    # # 字段隐藏:收藏数隐藏显示
    # exclude = ['fav_nums']
    # # 注意字段只读和字段隐藏是冲突的,不允许设置一个字段只读同时隐藏

    # 课程直接添加章节,课程资源
    inlines = [LessonInline, CourseResourceInline]

    # 过滤列表中的数据
    def queryset(self):
        qs = super(CourseAdmin, self).queryset()
        qs = qs.filter(is_banner=False)
        return qs


class BannerCourseAdmin(object):
    list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'fav_nums', 'image', 'click_nums',
                    'add_time']  # 一次显示你想出现的多行数据
    search_fields = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'fav_nums', 'image',
                     'click_nums']  # 查询你想要的数据
    list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'fav_nums', 'image', 'click_nums',
                   'add_time']  # 过滤器
    # # 默认排序:以点击数排序
    # ordering = ['-click_nums']
    #
    # # 字段只读:点击数只允许读取
    # readonly_fields = ['click_nums', 'fav_nums']
    #
    # # 字段隐藏:收藏数隐藏显示
    # exclude = ['fav_nums']
    # # 注意字段只读和字段隐藏是冲突的,不允许设置一个字段只读同时隐藏

    # 课程直接添加章节,课程资源
    inlines = [LessonInline, CourseResourceInline]

    # 过滤列表中的数据
    def queryset(self):
        qs = super(BannerCourseAdmin, self).queryset()
        qs = qs.filter(is_banner=True)
        return qs


xadmin.site.register(BannerCourse, BannerCourseAdmin)

然后刷新一下后台页面,发现有2个课程管理:

所以我们还是要配置一下:打开users/adminx.py文件,新增以下代码:

代码语言:txt
复制
from courses.models import BannerCourse

{'title': '轮播课程', 'url': self.get_model_url(BannerCourse, 'changelist')},

并修改之前的course的verbose_name为普通课程。

就是这个样子:

刷新一下我们的后台页面:

直接列表页编辑

在courses/adminx.py文件的CourseAdmin函数,新增一行代码:

代码语言:txt
复制
 # 直接列表页编辑
    list_editable = ['degree', 'desc', ]

列表页显示章节数

在courses/adminx.py文件的CourseAdmin和BannerCourseAdmin函数的list_display中,新增显示字段get_zj_nums,刷新后台发现是黑色的英文,我们需要修改,新增一行代码:

代码语言:txt
复制
get_zj_nums.short_description = "章节数"

显示自定义的html代码

在刚才的页面下面新增以下代码:

代码语言:txt
复制

def go_to(self):

代码语言:txt
复制
    from django.utils.safestring import mark_safe
代码语言:txt
复制
    # 如果不使用mark_safe,系统则会对其进行转义
代码语言:txt
复制
    return mark_safe("<a href='http://blog.licheetools.top'>跳转</>")
代码语言:txt
复制
go_to.short_description = "跳转"
代码语言:txt
复制
就是这个样子:
![](https://upload-images.jianshu.io/upload_images/8964398-e52c998057f7f32d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 列表页定时刷新
打开courses/adminx.py文件,在之前的CourseAdmin函数里面,新增一行代码:

refresh_times = 3,5 # 列表页定时刷新3s或者5s

代码语言:txt
复制
## 字段联动功能
打开courses/adminx.py文件,在之前的CourseAdmin函数里面,新增以下代码:

字段联动

代码语言:txt
复制
def save_models(self):
代码语言:txt
复制
    # 在保存课程的时候,统计课程机构的课程数
代码语言:txt
复制
    obj = self.new_obj
代码语言:txt
复制
    # 新增课程还没有保存,统计的课程数就会少一个
代码语言:txt
复制
    obj.save()
代码语言:txt
复制
    # 必须确定存在
代码语言:txt
复制
    if obj.course_org is not None:
代码语言:txt
复制
        # obj实际是一个course对象
代码语言:txt
复制
        course_org = obj.course_org
代码语言:txt
复制
        course_org.course_nums = Course.objects.filter(course_org=course_org).count()
代码语言:txt
复制
        course_org.save()
代码语言:txt
复制
## xadmin源码目录简说
![](https://upload-images.jianshu.io/upload_images/8964398-8a5ca28f1ab83af8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- locale  对应语言包
- migrations 是数据表的记录
- plugins 每一个后台页面都是一个plugin插件
- static 静态文件夹,里面有js,css
- template 这是xadmin自己使用的html文件
- templatetags  这是tag模板
总而言之,xadmin它是对Django admin的封装和进阶开发,正所谓青出于蓝而胜于蓝就是这个理。

## xadmin集成富文本
首先点击[Xadmin 插件制作](https://xadmin.readthedocs.io/en/docs-chinese/make_plugin.html),我们学着官网的介绍,自己尝试做一个插件:富文本编辑器。
点击[DjangoUeditor](https://github.com/zhangfisher/DjangoUeditor),获取**DjangoUeditor**的安装包,然后按照帮助文档或者下面的要求安装DjangoUeditor。
### 1、安装方法(注意需要转到eduline这个虚拟环境下面才能安装)

方法一:将github整个源码包下载回家,在命令行运行:

代码语言:txt
复制
python setup.py install
  • 方法二:使用pip工具在命令行运行(推荐): pip install DjangoUeditor### 2、在Django中安装DjangoUeditor 在INSTALL_APPS里面增加DjangoUeditor app,如下: eduline/settings.py文件:

INSTALLED_APPS = ( #........ 'DjangoUeditor', )

代码语言:txt
复制
### 3、配置urls 

eduline/urls.py文件:

富文本相关path配置

代码语言:txt
复制
path("ueditor/", include('DjangoUeditor.urls')),
代码语言:txt
复制
### 4、在models中的使用

courses/models.py文件:

from DjangoUeditor.models import UEditorField

class Course(models.Model):

代码语言:txt
复制
detail = UEditorField(verbose_name='课程详情', width=600, height=300, imagePath="courses/ueditor/",
代码语言:txt
复制
                                     filePath="courses/ueditor/", default='')
代码语言:txt
复制
### 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):

代码语言:txt
复制
def __init__(self,**kwargs):
代码语言:txt
复制
    self.ueditor_options=kwargs
代码语言:txt
复制
    self.Media.js = None
代码语言:txt
复制
    super(XadminUEditorWidget,self).__init__(kwargs)

class UeditorPlugin(BaseAdminPlugin):

代码语言:txt
复制
def get_field_style(self, attrs, db_field, style, **kwargs):
代码语言:txt
复制
    if style == 'ueditor':
代码语言:txt
复制
        if isinstance(db_field, UEditorField):
代码语言:txt
复制
            widget = db_field.formfield().widget
代码语言:txt
复制
            param = {}
代码语言:txt
复制
            param.update(widget.ueditor_settings)
代码语言:txt
复制
            param.update(widget.attrs)
代码语言:txt
复制
            return {'widget': XadminUEditorWidget(**param)}
代码语言:txt
复制
    return attrs
代码语言:txt
复制
# 在我们生成的页面中放入自己的js文件
代码语言:txt
复制
def block_extrahead(self, context, nodes):
代码语言:txt
复制
    js = '<script type="text/javascript" src="%s"></script>' % (settings.STATIC_URL + "ueditor/ueditor.config.js")         #自己的静态目录
代码语言:txt
复制
    js += '<script type="text/javascript" src="%s"></script>' % (settings.STATIC_URL + "ueditor/ueditor.all.min.js")   #自己的静态目录
代码语言:txt
复制
    nodes.append(js)

新增页面

xadmin.site.register_plugin(UeditorPlugin, UpdateAdminView)

修改页面

xadmin.site.register_plugin(UeditorPlugin, CreateAdminView)

代码语言:txt
复制
### 6、字段显示样式

courses/adminx.py文件:

class CourseAdmin(object):

代码语言:txt
复制
# 字段显示样式
代码语言:txt
复制
style_fields = {"detail": "ueditor"}
代码语言:txt
复制
### 7、注册进入plugins
找到plugins文件夹下的__init__.py文件,在PLUGINS中写入 

PLUGINS= ('ueditor',)

代码语言:txt
复制
就是这样:![](https://upload-images.jianshu.io/upload_images/8964398-9f83eb8f6ee980af.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

然后运行一下我们的项目,登录到xadmin后台查看一下,富文本出来:
![](https://upload-images.jianshu.io/upload_images/8964398-34540482f02c3dda.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
接着在前端刷新一下页面,如果没有出现:
![](https://upload-images.jianshu.io/upload_images/8964398-e930ce38bb41ca76.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
那可能是你的course-detail.html页面中设置的有问题:
![](https://upload-images.jianshu.io/upload_images/8964398-2429c372ce0499cb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
弄好以后,页面还是现实元原始的html代码,这是不允许的,所以我们需要进一步配置:在course-detail.html页面中,关闭转义功能:

{% autoescape off %}

{{ course.detail }}

{% endautoescape %}

代码语言:txt
复制

现在重新刷新一下我们的页面:

至此,本篇关于xadmin进阶开发的介绍就到此为止了,感谢你的赏阅!

本篇笔记对应于第二十六篇代码,对应于github的位置是https://github.com/licheetools/eduline

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于博主
  • 写在前面
  • 自定义icon
  • 默认排序,字段只读,字段隐藏
  • 搜索框
  • inlines添加数据
  • 一张表分两个model来进行管理
  • 直接列表页编辑
  • 列表页显示章节数
  • 显示自定义的html代码
  • 字段联动
  • 富文本相关path配置
  • 新增页面
  • 修改页面
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档