SharEDITor

从0到1搭建个人网站 四-强大的后台管理工具django-admin

全栈技术 从0到1搭建个人网站 发表于 2017-07-13 17:03:24 阅读1575次


每个web框架都配套有一个admin组件,用来管理后台数据库,django也有自己的django-admin,本节介绍一下它的使用

请尊重原创,转载请注明来源网站www.shareditor.com以及原始链接地址

django-admin的账户管理

当我们直接打开http://127.0.0.1:8000/admin时,虽然能够看到管理后台登陆界面,但是我们没有账号密码是无法登陆的,需要我们初始化一个超级用户,那么方法如何呢?我们可以通过执行python manager.py输出的提示来找到createsuperuser这个命令,执行:

python manage.py createsuperuser

按照提示输入账号、邮箱、密码,然后再次进入http://127.0.0.1:8000/admin就可以登陆了

登陆进入后我们看到了Group和Users两个管理项,这实际上对应着数据库里的auth_group和auth_user表,在Users里能看到我们刚刚创建的超级用户,在这里我们可以添加新的用户,并为不同用户配置不同权限

 

配置admin管理数据库

还记得上一节我们创建的三个Model及其数据库表吗?BlogPost、Subject、Tag,那么怎么才能在django-admin管理后台管理这三个表的内容呢?

修改web/admin.py,添加如下内容:

from django.contrib import admin
from .models import BlogPost

class BlogPostAdmin(admin.ModelAdmin):
    list_display = ('title', 'create_time', 'subject', 'tags')

admin.site.register(BlogPost, BlogPostAdmin)

重新登陆http://127.0.0.1:8000/admin管理页面,我们看到:

点进去可以看到文章的管理页面,因为我们在BlogPost这个model里设置的subject和tags字段不可以为空,因此我们需要提前添加类别和标签,下面我们再完善一下Subject和Tags的管理类,如下:

class SubjectAdmin(admin.ModelAdmin):
    list_display = ('name',)

class TagAdmin(admin.ModelAdmin):
    list_display = ('name',)

admin.site.register(Subject, SubjectAdmin)
admin.site.register(Tag, TagAdmin)

这时我们再尝试在管理页面新建一个Subject、一个Tag、一个BlogPost吧,建好之后可以在后台数据库直接查看到数据已经写到了数据库中

 

管理界面的定制化

爱美的同学可能会发现后台管理界面还不够漂亮和友好,比如页面顶部写的“Django administrator”能不能换成“SharEDITor管理后台”,比如管理首页里的“WEB”能不能改成“网站”,“Blog posts”能不能改成“文章”,另外我们在新建BlogPost的时候,类别和标签这两项里写的是“Subject object”和"Tag object",都不知道具体信息,下面我们来各个击破做一下定制

首先我们修改web/models.py,为Subject类添加如下成员:

class Meta:
    verbose_name_plural = '类别'

def __unicode__(self):
    return self.name

再为Tag类添加如下成员:

class Meta:
    verbose_name_plural = '标签'

def __unicode__(self):
    return self.name

再为BlogPost类添加如下成员:

class Meta:
    verbose_name_plural = '文章'

def __unicode__(self):
    return self.title

解释一下,这里的verbose_name_plural就是在这个结构在管理页面里的展示名称,__unicode__就是这个结构里每一个对象的展示形式,不用多说,直接看一下你的管理页面的效果就知道了

管理页面总标题因为是django-admin自身的内容,因此做定制有些复杂些,此处新手可以略过

请尊重原创,转载请注明来源网站www.shareditor.com以及原始链接地址

在根目录下创建如下目录templates/admin,并新建base_site.html文件,内容如下:

{% extends "admin/base.html" %}
{% load i18n %}

{% block title %}{{ title }} | {% trans 'SharEDITor后台管理' %}{% endblock %}

{% block branding %}
<h1 id="site-name">{% trans 'SharEDITor后台管理' %}</h1>
{% endblock %}

{% block nav-global %}{% endblock %}

修改shareditor/settings.py文件,在TEMPLATES  =>  DIRS配置项中添加'templates',这样就可以自动找到模板目录了,实际上这里的admin/base_site.html是重写了django-admin的源码。重新打开后台管理界面看下效果吧

 

图片管理(高级内容,新手略过)

我们在新建一个类别的时候要为image字段选择一张图片,我们看到图片实际上上传到了根目录下。这种方式存在一些问题:1)如果要在网站中展示这张图片需要为其单独指定路由;2)如果网站多机部署无法实时同步数据;3)如果图片很大,会耗费很多带宽,响应慢

为了解决如上问题,我们引入阿里云的对象存储OSS服务(收费,但不贵,这里不是帮阿里云打广告,但是阿里云确实做的比较好),它的优点是有CDN加速,也就是不同地域都有镜像,访问快,而且价格低廉,可比同样的网络带宽便宜多了

OSS的使用请见官方文档,我这里直接贴代码,懂的可以参考,不懂的可以直接用

首先要在阿里云的OSS中创建一个Bucket,如shareditor-shareditor,读写权限一定要选择“公共读”

其次要安装oss2库,执行:

pip install oss2

然后在我们代码的根目录创建commons目录(用于放置所有公共组件),并在其中创建一个空的__init__.py(作为lib的目录都要有这个文件,否则无法import),并创建ossutils.py文件,内容如下:

# -*- coding: utf-8 -*-
import oss2
import time

AccessKeyId = '你的AccessKey'
AccessKeySecret = '你的AccessKey密码'
Endpoint = 'oss-cn-beijing.aliyuncs.com'
InternalEndpoint = 'oss-cn-beijing-internal.aliyuncs.com'


def upload_oss(bucket_name, file_name, bytes_content):
    """
    :param bucket_suffix: 区分测试环境和线上环境
    :param file_name: 会自动添加时间戳
    :param bytes_content: 二进制的文件内容
    :return: 外网可以访问的url
    """
    auth = oss2.Auth(AccessKeyId, AccessKeySecret)
    bucket = oss2.Bucket(auth, Endpoint, bucket_name)
    file_path = 'dynamic/' + str(int(time.time())) + '_' + file_name
    result = bucket.put_object(file_path, bytes_content)
    if result.status == 200:
        return 'http://' + bucket_name + '.oss-cn-beijing.aliyuncs.com/' + file_path
    else:
        return None

下面我们重载Subject的image的上传逻辑,修改web/admin.py,引入ossuitls:

from commons.ossutils import upload_oss

声明BucketName变量下面会用到:

BucketName = 'shareditor-shareditor'

修改SubjectAdmin类,添加如下方法:

def save_model(self, request, obj, form, change):
    if 'image' in request.FILES:
        image_name = request.FILES['image'].name
        image_content = request.FILES['image'].read()

        url = upload_oss(BucketName, image_name, image_content)
        if url:
            obj.image = url

    super(SubjectAdmin, self).save_model(request, obj, form, change)

这时我们重新修改一个类目,重新上传图片,我们发现图片已经不再保存到本地文件了,而在阿里云的OSS里找到了上传的文件,而在我们的数据库里存储了这个图片在阿里云OSS中的url,可以直接访问

 

总结

有关admin管理后台的内容以上这些基本够用了,剩下的就是根据你的业务逻辑去设计自己的表结构,发挥自身的主动性啦