二、后台管理系统的设计

添加超级用户

Django有一套自带的后台管理系统, 比如我们可以直接建立超级用户:

python3 manage.py createsuperuser

Django的后台系统默认是英文的, 如果我们想改成中文的, 可以在settings.py里配置:

#settings.py

...
#中文
LANGUAGE_CODE = 'zh-hans'
#时区
TIME_ZONE = 'Asia/Shanghai'
#使用本地时间
USE_TZ = False

后台页面管理

现在,我们可以通过runserver命令进入后台管理系统,目前只能看到用户和用户组两个数据表。除此之外,我们可以将某些Django app中定义的models表添加到后台进行管理,具体操作是在对应APP目录下的admin.py中添加信息,比如我们想把blogs这个app中设计的Article这个model注册到后台, 我们需要在blogs/admin.py中编写如下代码:

#blogs/admin.py
from django.contrib import admin
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    pass

admin.site.register(Article,ArticleAdmin)

这样我们的后台页面就多了一张数据表。

用户信息表的扩展

Django给我们设计了一个默认的后台用户信息表的Model, 其表结构我们可以在后台数据库中的auth_user表看到,建表语句如下:

CREATE TABLE `auth_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT, #主键
  `password` varchar(128) NOT NULL, #密码
  `last_login` datetime(6) DEFAULT NULL, #Django自动记录最后登录时间
  `is_superuser` tinyint(1) NOT NULL, #是否是超级用户
  `username` varchar(150) NOT NULL, #用户名
  `first_name` varchar(150) NOT NULL, #名
  `last_name` varchar(150) NOT NULL, #姓
  `email` varchar(254) NOT NULL, #邮箱
  `is_staff` tinyint(1) NOT NULL, #是否是员工
  `is_active` tinyint(1) NOT NULL, #是否激活
  `date_joined` datetime(6) NOT NULL, #用户注册时间
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

如果我们觉得这些字段仍然不满足需求,我们可以基于此表自定义一个用户信息扩展表。

创建Users的app

首先,我们需要在项目中添加一个用户系统的app, 用于处理users的事务:

python3 manage.py startapp users<app的名称>

注意在settings.py中配置新增的app:

#users/settings.py
...
INSTALLED_APPS = [
    ...
    "users"
]
...
设计Users Model

接下来, 我们需要设计users app的model.py文件中添加数据模型信息。Django给我们提供了一个AbstractUser的抽象类,该类拥有auth_user表中所有字段,使得我们可以通过继承该类,在已有的用户信息字段基础上扩展出新的用户信息表:

#users/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser


class UserProfile(AbstractUser):
    nick_name = models.CharField(max_length=50, verbose_name='昵称',default="")
    birday = models.DateField(verbose_name='生日',null=True,blank=True)
    gender = models.CharField(max_length=10,choices=(("male","男"),("female","女")),default="female")
    address = models.CharField(max_length=100,default="")
    mobile = models.CharField(max_length=11, null=True, blank = True)
    image = models.ImageField(max_length=100,upload_to="image/%Y/%m",default="image/default.png")
    
    class Meta:
        verbose_name = "用户信息"
        verbose_name_plural = verbose_name
        
        
    def __unicode__(self):
        return self.username

另外,我们需要在settings.py中添加下面这行代码,其作用是为Django指定一个新的用户数据表来替代老的auth_user表:

#settings.py
...
AUTH_USER_MODEL = "users.UserProfile"
...
同步用户数据信息

最后,我们需要执行以下两行命令,将新的后台用户信息同步到数据库中:

python3 manage.py makemigrations
python3 manage.py migrate

注意:如果由于之前已经存在的admin的表对项目默认的auth_user表有依赖,导致在同步中报错,可以先清除掉原来的auth_user表,再执行这两行命令(反正现在没有业务数据)。

后台用户的登录校验

Dango自带的一个用户验证方法authenticate,默认通过username和password进行验证,如果验证成功,该方法将返回一个user对象,否则返回None。此外,Django允许我们使用自定义验证方式,如下所示,我们通过继承类ModelBackend来重写authenticate方法,用Q实现或逻辑:

#users/views.py
from django.shortcuts import render
from django.contrib.auth import authenticate,login
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from .models import UserProfile


class CustomBackend(ModelBackend):
    def authenticate(self,username=None,password=None,**kwargs):
        try:
            user = UserProfile.objects.get(Q(username=username)|Q(email=username))
            if user.check_password(password):
                return user
        except Exception as e:
            return None
    def user_login(request):
        if request.method == 'POST':
            user_name = request.POST.get('username',"")
            pass_word =  request.POST.get('password',"")
            user = authenticate(username=user_name,password=pass_word)
            if user is not None:
                login(request,user)
                return render(request,"login.html")
            else:
                return render(request,'login.html',{"msg":"用户名或密码错误!"})
        elif request.method == 'GET':
            return render(request,'login.html',{})
#urls.py
...
from users.views import user_login

urlpatterns = [
    ...
    url('^login/$',user_login,name='login')
]

如果我们选择自定义后台用户校验逻辑,则需要在settings.py中指定我们使用的校验类:

#settings.py
...
AUTHENTICATION_BACKENDS = (
    'users.views.CustomBackend',
)

views.py中还用到了login,这个方法将通过request记录下用户的地址,通过session和cookies记录用户的状态。Django的前端可以通过{% request.user.is_authenticated %}判断用户是否验证。

DjangoUeditor

为了给我们的文章添加一个富文本编辑器, 我们使用DjangoUeditor, 我们在官网或者git上下载下对应版本的DjangoUeditor后, 在项目目录下新建一个文件夹extra_apps, 将DjangoUeditor文件夹放入该目录下, 在settings.py中进行设置:

#settings.py

...
sys.path.insert(0,os.path.join(BASE_DIR,'extra_apps'))
INSTALLED_APPS = [
    ...
    'DjangoUeditor',
]

另外在urls.py中也需要进行设置:

#urls.py
...

urlpatterns = [
    ...
    url(r'^ueditor/',include('DjangoUeditor.urls')),
]

最后, 当需要使用对应的models时需要使用以下设置:

#models.py
...
from DjangoUeditor.models import UEditorField

class XXmodels(models.Model):
    ...
    content = UEditorField(default='', blank=True, width=1000, imagePath='uploads/blog/images/',filePath='uploads/blog/files/', verbose_name='文章内容')

引入强大的Xadmin

Xadmin是基于Django的admin扩展我们的后台功能的管理系统,
安装方式如下:

pip install xadmin

安装成功后, 我们需要在settings.py中注册两个APP:

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

之后, 我们需要在urls.py中修改admin的映射关系:

#urls.py
from django.conf.urls import url
from django.contrib import admin
import xadmin

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

另外, users/admin.py中也不能用默认的admin的注册方式了:

#users/admin.py
from django.contrib import admin

实际上, 我们需要在每个app下新建一个adminx.py文件:

#users/adminx.py

import xadmin
from .models import EmailVerifyRecord

class EmailVerifyRecordAdmin(object):
    #后台展示哪些字段, 可以不设置
    list_display = ['code','email']
    #后台在哪些字段中进行搜索
    search_fields = ['']

xadmin.site.register(EmailVerifyRecord,EmailVerifyRecordAdmin)

之后使用makemigrations和migrate同步xadmin的表结构, 之后重启系统就可以。

Xadmin的一些设置

xadmin有一些用户可以自定义的设置。

#users/adminx.py
...
from xadmin import views

#使用主题功能,变更系统配色
class BaseSetting(object):
    enable_themes = True
    use_bootswatch = True
    
xadmin.site.register(views.BaseAdminView,BaseSetting)


class GlobalSettings(object):
    #修改角标
    site_title = "终极奥义"
    site_footer = "眼君数据"
    #左侧菜单栏收缩
    menu_style = "accordion"
    
xadmin.site.register(views.CommAdminView,GlobalSettings)

每一个APP都有一个apps.py文件, xadmin可以设置系统中APP的名称:

#users/apps.py
from django.apps import AppConfig
class UserConfig(AppConfig):
    name = 'users'
    verbose_name = '用户信息'
#users/__init__.py
default_app_config = "users.apps.UserConfig"
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容