蒋振飞的博客 - 网站搭建 (第14天) xadmin后台强化   
正在加载蒋振飞的博客...
V3.0
蒋振飞的博客

网站搭建 (第14天) xadmin后台强化

发布时间: 2018年08月26日 发布人: 蒋振飞 热度: 952 ℃ 评论数: 2

一、前言

昨天在逛开源中国社区时,偶然在推荐中看到有关xadmin的文章,一想到Django自带的后台不是admin吗,难道它们之间有某种联系?果不其然,还真的是,xadmin就是admin的后台强化版,除强化一些功能外还增加了许多admin中没有的设计。举个例子:如使用Bootstrap作为UI框架,灵活且可自定义的页面布局,主页仪表板和小部件,字体图标和模型图标,即时编辑,图表功能,相关信息菜单等等。详细内容请查看文档:Django Xadmin

下面就从安装开始介绍xadmin的使用方法,替换行动开始。

首先我也是在网络上各种找方案,找解决办法,我也不明白为什么有些错误大家也互相抄来抄去,对后来学习的人造成了很大的困扰,所以还是要擦亮眼睛去对待。

二、xadmin的安装

方案一:使用pip直接安装xamdin

pip install xadmin

方案二:通过git下载到本地

git clone https://github.com/XiaoFei-97/xadmin.git

方案三:直接在进入到https://github.com/XiaoFei-97/xadmin,然后Download压缩文件。

其中方案一我试了安装不成功,总是出现丢包的问题,可能很多依赖没有自动下载,所以我选择方案二,方案三也是可行的,下载后解压缩可以看到

├── build
├── changelog.md
├── changelog.sh
├── demo_app
├── dist
├── LICENSE
├── MANIFEST.in
├── README.rst
├── requirements.txt
├── setup.py
├── tests
├── xadmin
└── xadmin.egg-info

三、xadmin的配置 

其实demo_app是一个小案例,我们只需要其中的xadmin文件夹,将其方法自己的项目根目录下,在settings.py里面注册上

INSTALLED_APPS = [
    # ........
    'xadmin',
    'crispy_forms',
]

修改urls.py

import xadmin
urlpatterns = [
    #url(r'^admin/', admin.site.urls),
    url(r'^xadmin/', xadmin.site.urls),
]

启动django

// 执行数据库迁移
python manage.py makemigrations
python manage.py migrate

// 运行服务
python manage.py runserver 8000

如果以上过程中都没有报错的话,就可以正常访问了。

830561-20170207112521057-2091903306.png

四、xadmin注册  

已经在models定义Post类

from django.db import models
from django.contrib.auth.models import User  # 引入USER
from django.contrib.contenttypes.fields import GenericRelation
from read_statistics.models import ReadNumExpandMethod, ReadDetail
from DjangoUeditor.models import UEditorField


class Post(models.Model, ReadNumExpandMethod):
    """
    文章的数据库表稍微复杂一点,主要是涉及的字段更多。
    """

    title = models.CharField(max_length=70, verbose_name=u'文章标题',)

    body = UEditorField(verbose_name=u'内容', width=800, height=500, toolbars="full", imagePath="images/", filePath="files/", upload_settings={"imageMaxSize": 1204000},)

    created_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
    modified_time = models.DateTimeField(verbose_name=u'修改时间', auto_now=True)

    excerpt = models.CharField(verbose_name=u'摘要', max_length=200, blank=True)

    category = models.ForeignKey(Category, verbose_name=u'分类')

    read_detail = GenericRelation(ReadDetail)

    author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=u'作者')

创建的app下创建adminx.py文件

class PostAdmin(object):
    """
    作用:自定义文章管理工具
    admin.ModelAdmin:继承admin.ModelAdmin类
    """
    
    # 在后台显示id值,博文名,创建时间,修改时间,目录,作者
    list_display = ['id', 'title', 'created_time', 'modified_time', 'category', 'author', 'get_read_num']
    
    # 增加过滤框,且以文章分类作过滤器
    list_filter = ['category', 'created_time', 'author']
    
    # 增加文章标题搜索字段
    search_fields = ['title']
    
xadmin.site.register(Post, PostAdmin)

最好还是创建另外一个adminx.py,不要在admin.py上直接修改,其实只要在之前的app注册时将admin应用注释掉就可以了,admin也留着不要删,毕竟陪伴过。其他的模型表也与此类似,就不赘述,但还有一个问题,我还遇到了content_object无法注册的情况,原因主要是因为我使用了GenericForeignKey这个外键,ForeignKey的外键还是可以一样注册的,至于GenericForeignKey的问题,我暂时只能通过在模型类下定义一个方法,使用object_id来filter出当前对应的文章。例如这是一个评论对象的获取,属于comment应用模型下的方法,至于评论功能,以后再作出介绍,这里先不用管。

def get_comment(self):
    # 此处的一个异常处理,用来捕获没有对象的情况
    # 例如在admin后台中,没有计数值会显示为‘-’
    try:
        post = Post.objects.get(id=self.object_id)
        return post.title
    # 对象不存在就返回0
    except exceptions.ObjectDoesNotExist:
        return 0

将应用名称和数据表显示为中文,对于数据表的显示,早在模型定义就应该被完成,如

title = models.CharField(max_length=70, verbose_name=u'文章标题',)
class Meta:
    verbose_name = '文章'
    verbose_name_plural = '文章'
    ordering = ['-created_time']

重要的是应用名称的修改,修改apps.py文件。

from django.apps import AppConfig

class BlogConfig(AppConfig):
    name = 'blog'
    verbose_name = u'博客'

还需要在该应用下的__init__.py下添加

default_app_config = "blog.apps.BlogConfig"

页头和页脚自定义。

class GlobalSetting(object):
    # 设置网站标题
    site_title = "后台管理系统"
    
    # 设置网站页脚
    site_footer = "蒋振飞的博客"
    
    # 设置应用图标
    # menu_style = "accordion"

xadmin.site.register(views.CommAdminView, GlobalSetting)

打开主题应用。

class BaseSetting(object):

    # 主题
    enable_themes = True
    use_bootswatch = True

xadmin.site.register(views.BaseAdminView, BaseSetting)

这个功能开启就可以通过按钮自定义更换主题颜色,不过我目前没有成功,只有默认和Bootstrap主题样式,网上的解释是当use_bootswatch 为True的时候,就会使用httplib2去http://bootswatch.com/api/3.json网址获取主题菜单项。但是使用浏览器打开这个网址,http会被替换成https的,httplib2访问这个https的网址,就会报错,然后使用requets代替之类的,我试过了,也终究没有成功。最后自己通过发现其是通过requests库来抓取json格式的文件,然后解析出css样式地址,最后在static中引用,那我为何不可自己通过下载css文件引用到static中,果然,最后成功了。

以Cerulean为例,首先在http://bootswatch.com/api/3.json下载css,添加到xadmin/static/xadmin/css/themes文件夹,并修改文件名为Cerulean-theme.css,然后在themes.py中添加

class ThemePlugin(BaseAdminPlugin):

    enable_themes = False
    # {'name': 'Blank Theme', 'description': '...', 'css': 'http://...', 'thumbnail': '...'}
    user_themes = None
    use_bootswatch = False
    default_theme = static('xadmin/css/themes/bootstrap-xadmin.css')
    bootstrap2_theme = static('xadmin/css/themes/bootstrap-theme.css')
    # Cerulean_theme是新添加的静态文件地址
    Cerulean_theme = static('xadmin/css/themes/Cerulean-theme.css')

最后一步,在block_top_navmenu方法下的themes添加

themes = [
    {'name': _(u"Default"), 'description': _(u"Default bootstrap theme"), 'css': self.default_theme},
    {'name': _(u"Bootstrap2"), 'description': _(u"Bootstrap 2.x theme"), 'css': self.bootstrap2_theme},
    # 新加天蓝色主题
    {'name': _(u"天蓝色"), 'css': self.Cerulean_theme},
]

最终效果如下,主页面的一些小组件是自己添加的

2018-08-26 09-03-34屏幕截图.png 

五、xadmin集成富文本编辑器Ueditor

xadmin已经整合的差不多了,但是细心的话会发现,之前使用Ueditor编辑器在编辑框消失了,所以我又来填坑了,至于安装Ueditor编辑器什么的,之前也在我的网站搭建 (第十天) Ueditor编辑器总结过,这里就直接区分xadmin与admin使用Ueditor的不同。

在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.js")  # 自己的静态目录
        nodes.append(js)

xadmin.site.register_plugin(UeditorPlugin, UpdateAdminView)
xadmin.site.register_plugin(UeditorPlugin, CreateAdminView)

在xadmin/plugins/__init__.py添加ueditor

 'ueditor'

配置adminx.py

class PostAdmin(object):
    """
        作用:自定义文章管理工具
        admin.ModelAdmin:继承admin.ModelAdmin类
    """
    # 后台管理每页显示20篇文章标题
    list_per_page = 20
    # 注意body是正文的字段名
    style_fields = {"body": "ueditor"}
    # 刷新时间间隔
    refresh_times = (60,)
 
xadmin.site.register(Post, PostAdmin)

打赏 蒋振飞

取消

感谢您的支持,我会继续努力的!

扫码支持
一分也是爱     一块不嫌多

点击 支付宝 或 微信 打赏蒋振飞

打开支付宝扫一扫,即可进行扫码打赏哦

评论列表