flask-admin 快速打造博客 系列二 (整合flask-admin)

minsons

整合flask-admin


前言

Flask-admin 相当django的xadmin吧!可是xadmin虽然样式很漂亮,功能也很强大,可是灵活性不够,官方文档缺失,这两个原因就足以让我选择不用了。
Flask-admin也是有使用局限性的,他只适合开发小型快速的应用,不适合那种大型并发性高,逻辑复杂的应用。首先,对于大型应用都是前后端分离的,加快访问速度,而且后端装配,尤其是这种动态生成页面的速度更慢。
对于一般的博客,小型的论坛或者官网之类的网站,其实页面真多不到那里去,用flask开发还是绰绰有余的。

1)基础整理flask-admin

from flask_admin import Admin
admin = Admin(app, name='cleanblog', template_mode='bootstrap3')
#template_mode 如果没有指定就默认bootstrap2的样式了

然后打开浏览器http://127.0.0.1:5005/admin/ 看到:

clipboard.png

2) 整合model到flask-admin

2.1我们先增加两个model

class Article(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title=db.Column(db.String(32))
    content=db.Column(db.Text,nullable=False)
    tag=db.Column(db.String(64),nullable=True)
    create_time = db.Column(db.DateTime, nullable=True, default=datetime.now)

    def __repr__(self):
        return '<User %r>' % self.title

数据模型

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32), nullable=False)
    desc = db.Column(db.String(64), nullable=True)
    create_time = db.Column(db.DateTime, nullable=True, default=datetime.now)

    def __repr__(self):
        return '<User %r>' % self.name

然后注册model到flask-admin中:

from .models import User,Tag,Article
from .modelview import BaseModelview
admin = Admin(app, name='cleanblog', template_mode='bootstrap3')

admin.add_view(BaseModelview(User, db.session,name=u'用户管理'))
admin.add_view(BaseModelview(Tag, db.session, name=u'标签管理'))
admin.add_view(BaseModelview(Article, db.session, name=u'文章管理'))

这里有一个定义的BaseModelview是作为一个全局的Modelview来用的,是为了自定义一些model的view界面上的显示的。

class BaseModelview(ModelView):
    def getinfo(self):
        return "this is another model"

里面什么都没有,如果后期扩展权限限制了,可以在这里加代码限制。
然后,重启服务:http://127.0.0.1:5005/admin/

在这里我们,我们就可以看到一些效果显示出来了,挺好看的。

clipboard.png

然后看一下新增文章的视图:

clipboard.png

不是富文本的,令人恨不能满意,那么就改为ckEditor的吧!官方有相应的支持,我们就直接看官网。

3)自定义调整样式

3.1 调整area区为富文本:使用ckEditor编辑器,官方提供的文档有说明在:
http://flask-admin.readthedoc... WYSIWIG Text Field 里面有
(1)直接拷贝相应的代码到 modelview.py

 class CKTextAreaWidget(TextArea):
    def __call__(self, field, **kwargs):
        if kwargs.get('class'):
            kwargs['class'] += ' ckeditor'
        else:
            kwargs.setdefault('class', 'ckeditor')
        return super(CKTextAreaWidget, self).__call__(field, **kwargs)

class CKTextAreaField(TextAreaField):
    widget = CKTextAreaWidget()

class MessageAdmin(BaseModelview):
    extra_js = ['//cdn.ckeditor.com/4.6.0/standard/ckeditor.js']

    form_overrides = {
        'content': CKTextAreaField
    }

前面两个类是直接官方拷贝过来的,后面一个继承我们的BaseModelview,然后再在
Form_overrides里写明content字段是使用CKTextAreaField的扩展就可以了。
(2)修改注册的article类:
admin.add_view(MessageAdmin(Article, db.session, name=u'文章管理'))

重启后,打开链接: http://127.0.0.1:5005/admin/article/new/?url=%2Fadmin%2Farticle%2F

4) 上传图片

官网有一个demo 就是讲怎么上传图片的https://github.com/flask-admi... 可以作为参考的
User里有一个头像img_head 字段,以此为例进行讲解:
(1) 自定义user的modelview

from sqlalchemy.event import listens_for
import os.path as op
import  os
from jinja2 import Markup

file_path = op.join(op.dirname(__file__), 'static') # 文件上传路径

class UserAdmin(BaseModelview):
    #设置缩略图的
    def _list_thumbnail(view, context, model, name):
        if not model.head_img:
            return ''

        return Markup('<img src="%s">' % url_for('static',
                                               filename=form.thumbgen_filename(model.head_img)))
    # 格式化列表的图像显示
    column_formatters = {
        'head_img': _list_thumbnail
    }
    #扩展列表显示的头像为60*60像素
    form_extra_fields = {
        'head_img': form.ImageUploadField('Image',
                                     base_path=file_path,
                                     relative_path='uploadFile/',
                                     thumbnail_size=(60, 60, True))
    }

其实还需要增加另一个类,用于sql的监听,但该用户被删除的时候,同时也在磁盘上把图片删除:

##监听删除图片的
@listens_for(User, 'after_delete')
def del_image(mapper, connection, target):
    if target.head_img:
        # Delete image
        try:
            os.remove(op.join(file_path, target.head_img))
        except OSError:
            pass

        # Delete thumbnail
        try:
            os.remove(op.join(file_path,
                              form.thumbgen_filename(target.head_img)))
        except OSError:
            pass

注意:head_img 字段名不能写错,写错就展示不了

(2)注册modelview 并重启服务
admin.add_view(UserAdmin(User, db.session,name=u'用户管理'))
重启后的结果:

clipboard.png

clipboard.png

(3) 修改表格头显示
表格头默认是显示是表的字段名,我们可以自定义为自己的中文显示,这一块还跟国际化无关,所以稍感郁闷啊。
在modelview.py 对应的自定义UserAdmin中加入

column_labels = {
    'id': u'序号',
    'email': u'邮件',
    'username': u'用户名',
    'role': u'角色',
    'password_hash': u'密码',
    'head_img': u'头像',
    'create_time':u'创建时间'
}

显示的结果:

clipboard.png

(4)隐藏显示字段
在用户显示的列表中,加密后的密码,通过我们是不希望显示出来的,那就把他隐藏掉:
column_exclude_list = [' password_hash', ]
modeview加入该字段后重启就有效果了:

clipboard.png

(5)其他自定义化功能:
其他自定义化功能很多,可以参考:http://flask-admin.readthedoc...
想增加过滤的字段:column_filters = ['country']
想设置可查询的字段:column_searchable_list = ['name', 'email']
想指定可编辑的字段:column_editable_list = ['name', 'last_name']
即不创建也不编辑的字段:form_excluded_columns = ['last_name', 'email']
增加可选择下拉框的:
form_extra_fields = {
'tag':form.Select2Field('请选择',choices=[('xiaoming','xiaoming'),('xiao2','xodk2')])
}

关于这些方法怎么查的到呢?
首先,你要想得到,有这方面的需求,然后再去base,baseview,ModelView等类中看源码,也可以去对应的官网查看api就能查到对应的解决方法。

阅读 23.3k

深圳九领贸易有限公司CTO,主要负责公司网站及商城的架构设计和发展规划,曾就业于IBM等公司。

55 声望
0 粉丝
0 条评论

深圳九领贸易有限公司CTO,主要负责公司网站及商城的架构设计和发展规划,曾就业于IBM等公司。

55 声望
12 粉丝
宣传栏