建立模型
编辑\myblog\system\models.py
追加以下内容,以下文件内创建
- 基本模型(所有模型的父类)
- 用户模型
- 邮件记录模型
from django.contrib.auth.models import AbstractUser
from django.db import models
import logging
logger = logging.getLogger('django')
"""
邮件类型
"""
class EmailType:
ACTIVE = "active"
RESET = "reset"
NOTICE = "notice"
CHECK = "check"
REPLY = "reply"
EMAIL_TYPE = (
(EmailType.ACTIVE, '注册激活'),
(EmailType.RESET, '找回密码'),
(EmailType.NOTICE, '评论通知'),
(EmailType.CHECK, '评论审核'),
(EmailType.REPLY, "评论回复"),
)
class BaseModel(models.Model):
id = models.BigAutoField(verbose_name="ID", primary_key=True, editable=False, unique=True)
creator = models.ForeignKey("system.User", verbose_name='创建者', on_delete=models.CASCADE, db_constraint=False,
related_name="%(app_label)s_creator_%(class)s", null=True, blank=True)
editor = models.ForeignKey("system.User", verbose_name='编辑者', on_delete=models.CASCADE, db_constraint=False,
related_name="%(app_label)s_editor_%(class)s", null=True, blank=True)
create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
update_time = models.DateTimeField(verbose_name="更新时间", auto_now=True)
class Meta:
abstract = True
default_manager_name = "admin_objects"
@staticmethod
def get_base_exclude_fields():
return [BaseModel.deleted.field.name,
BaseModel.creator.field.name,
BaseModel.editor.field.name]
class User(AbstractUser, BaseModel):
link = models.URLField(verbose_name='个人网址', null=True, blank=True)
avatar = models.ImageField(verbose_name='头像', upload_to="avatar/", default="avatar/default.png")
introduction = models.CharField(max_length=50, null=True, blank=True)
nickname = models.CharField(verbose_name='昵称', max_length=100, null=True, blank=True)
is_active = models.BooleanField(verbose_name="是否激活", default=True)
class Meta(BaseModel.Meta):
db_table = "sys_user"
verbose_name = "用户"
verbose_name_plural = verbose_name
ordering = ['-last_login']
def __str__(self):
return self.username
class EmailRecord(BaseModel):
receiver = models.ForeignKey(User, verbose_name="收件人", related_name="user_email_record", on_delete=models.CASCADE)
url = models.URLField(verbose_name="访问url", null=True, blank=True)
code = models.CharField(verbose_name="验证码", max_length=200)
email_type = models.CharField(verbose_name="邮件类型", choices=EMAIL_TYPE, max_length=50)
comment_id = models.BigIntegerField(verbose_name="评论Id", help_text="用来审核评论的", null=True, blank=True)
class Meta:
ordering = ("-create_time",)
db_table = "sys_email_record"
verbose_name = '邮件记录'
verbose_name_plural = verbose_name
BaseModel是一个抽象的基本模型,包含每个模型的公共字段。后面所有的模型都会继承该抽象模型。system应用下提供用户模型和邮件记录模型。
接下来需要迁移模型,同样操作选择Tools->Run manage.py Task,操作如下图
或者在当前项目位置打开终端执行以下命令
python manage.py makemigrations
python manage.py migrate
注册模型
编辑\mybloh\system/admin.py
from django.contrib.admin import ModelAdmin, register, site
from system import models
site.site_header = '博客后台管理系统'
site.site_title = '博客后台管理系统'
class BaseModelAdmin(ModelAdmin):
list_per_page = 10
list_max_show_all = 10
def get_exclude(self, request, obj=None):
if not request.user.is_superuser:
return models.BaseModel.get_base_exclude_fields()
return None
def save_model(self, request, obj, form, change):
if change:
obj.creator = request.user if not obj.creator else obj.creator
obj.editor = request.user
super(BaseModelAdmin, self).save_model(request, obj, form, change)
@register(models.User)
class UserModelAdmin(BaseModelAdmin):
list_display = ['username', 'nickname', 'email', 'link', 'is_active', 'is_superuser']
list_filter = ['username', 'email']
search_fields = ['username', 'email']
list_editable = ["is_active", "is_superuser"]
list_per_page = 20
@register(models.EmailRecord)
class EmailRecordModelAdmin(BaseModelAdmin):
list_display = ['id', 'email_type', 'receiver', 'url']
list_filter = ['email_type', 'receiver__username']
search_fields = ['receiver__username', 'receiver__email']
接下来需要创建超级用户,同样操作选择Tools->Run manage.py Task,操作如下图
或者在当前项目位置打开终端执行以下命令
python manage.py createsuperuser
接下来让我们启动项目访问后台http://127.0.0.1:8000/admin
输入我们刚刚创建的用户名和密码,成功返回以下页面表示ok
自定义登录验证
编辑\myblog\myblog\system\views.py
from django.db.models import Q
"""
自定义用户登陆验证逻辑(实现用户名或邮箱登陆)
"""
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = User.objects.get(Q(username=username) | Q(email=username))
if user.check_password(password):
return user
except User.DoesNotExist as e:
return None
编辑\myblog\myblog\settings.py,添加以下配置
# 自定义认证后台
AUTHENTICATION_BACKENDS = ['system.views.CustomBackend']
这样配置完成后,可以再次访问admin后台,输入之前创建的邮箱+密码也可以登录成功了。
美化后台
django-simpleui 是一款django admin 的一个主题 ,基于element-ui+vue开发,可以让我们的后台管理系统看起来更好看。
新增\myblog\myblog\simpleui_settings.py
# 首页配置
# SIMPLEUI_HOME_PAGE = 'https://www.baidu.com'
# 首页标题
# SIMPLEUI_HOME_TITLE = '百度一下你就知道'
# 首页图标,支持element-ui的图标和fontawesome的图标
# SIMPLEUI_HOME_ICON = 'el-icon-date'
# 设置simpleui 点击首页图标跳转的地址
SIMPLEUI_INDEX = 'https://www.88cto.com'
# 首页是否显示服务器、python、django、simpleui相关信息
SIMPLEUI_HOME_INFO = False
# 首页显示快速操作
SIMPLEUI_HOME_QUICK = True
# 首页显示最近动作
SIMPLEUI_HOME_ACTION = True
# 自定义SIMPLEUI的Logo
# SIMPLEUI_LOGO = 'https://avatars2.githubusercontent.com/u/13655483?s=60&v=4'
# 登录页粒子动画,默认开启,False关闭
# SIMPLEUI_LOGIN_PARTICLES = False
# simpleui是否收集相关信息
SIMPLEUI_ANALYSIS = False
# 自定义simpleui 菜单
# SIMPLEUI_CONFIG = {
# 'system_keep': True, # 在自定义菜单的基础上保留系统模块
# 'menus': [
# {
# 'name': 'Simpleui',
# 'icon': 'fas fa-code',
# 'url': 'https://gitee.com/tompeppa/simpleui'
# },
# {
# 'name': '搜索引擎',
# 'icon': 'fa fa-list',
# 'models': [{
# 'name': '百度',
# 'url': 'http://baidu.com',
# 'icon': 'fa fa-list'
# }, {
# 'name': '谷歌',
# 'url': 'https://google.com',
# 'icon': 'fa fa-list'
# }]
# }]
# }
# 是否显示默认图标,默认=True
# SIMPLEUI_DEFAULT_ICON = False
# 图标设置,图标参考:
# SIMPLEUI_ICON = {
# '员工管理': 'fas fa-user-tie'
# }
# 指定simpleui 是否以脱机模式加载静态资源,为True的时候将默认从本地读取所有资源,即使没有联网一样可以。适合内网项目
# 不填该项或者为False的时候,默认从第三方的cdn获取
SIMPLEUI_STATIC_OFFLINE = True
# 默认主题 设置
SIMPLEUI_DEFAULT_THEME = 'x-blue.css'
编辑\myblog\myblog\settings.py,修改以下内容
....
INSTALLED_APPS = [
'simpleui',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'system'
]
....
from myblog.simpleui_settings import *
这里注册simpleui应用需要注意将 simpleui 注册到 INSTALLED_APPS 的放在第一个