1) 确保表里的字段都缺一不可(也就是具有原子性)
2) 确保表里的字段都和主键直接相关
[内容] MariaDB & MySQL 事务
内容一:事务的作用
事务的作用是保护数据的安全性
内容二:MariaDB & MySQL 事务的 4 大特性
2.1 原子性(Atomicity)
一系列操作被看作一个事务,这个事务里面的所有操作要么全部失败,要么全部成功,如果在操作的过程中出现中断,则立刻进行 rollback
2.2 一致性(Consistency)
一系列操作被看作一个事务,在事务开始前和结束后,整个库的完整逻辑约束不能被打破,例如:一个人向另一个人转账,不能出现一个人转账成功另一个人没有收到转账,或者一个人转账失败另一个人收到转账的情况
2.3 隔离性(Isolation)
主要解决并发的情况,避免不同的人,在相同的时间,查看到的数据的不一致性,避免以下情况的发生:
1) 脏读:一个事务读取了另一个事务更新、提交并撤销的数据,导致此事务看到的数据是错误的
2) 不可重复读:一个事务多次读取了另一个事务多次更新并提交的数据,导致此事务看到的数据是来回变化的
3) 幻读:一个事务在批量修改所有数据,但是在修改的过程中另一个事务又往里面插入了数据,导致此事务在修改完成之后,意外发现还有一条数据没有修改
2.4 持久性(Durability)
事务结束后,所有更新都将被保存,不能回滚
内容三:MariaDB & MySQL 事务隔离级别
3.1 MariaDB & MySQL 事务隔离级别的特点
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read-uncommitted) | 是 | 是 | 是 |
不可重复读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
3.2 MariaDB & MySQL 默认的事务隔离级别
可重复读 repeatable-read
3.3 查看目前所使用的事务隔离的方法
MariaDB [(none)]> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.001 sec)
(补充:这里以查看 MariaDB 目前所使用的事务隔离为例)
[内容] MariaDB & MySQL 多表关系
内容一:一对一关系
1.1 通常实现方法
唯一外键
1.2 典型案例
学生表和学生证表
内容二:一对多关系
2.1 通常实现方法
主外键
2.2 典型案例
学生表和班级表
内容三:多对多关系
3.1 通常实现方法
中间表加联合主键
(补充:联合主键是指一张表中有两个主键,这两个主键叫联合主键,每一条数据里的联合主键可以相互之间拼凑成一个新的主键,联合主键可以重复,只要保证这个新的主键唯一即可)
3.2 典型案例
学生和课程
[工具] Shell 自动化部署 LNMP + SSL 平台 (openSUSE Leap 15 版)
介绍
基本信息
作者:朱明宇
名称:自动化部署 LNMP + SSL 平台
作用:自动化安装 LNMP + SSL,即通过 Linux、Nginx、MariaDB、PHP、php-fpm、SSL,实现 HTTPS
使用方法
1. 将网站的网页数据备份、网站的 SSL 公钥、网站的 SSL 私钥、网站的数据库备份和本脚本,5 个文件放在同一目录下
2. 如果没有网站的数据库备份则将网页数据备份、网站的 SSL 公钥、网站的 SSL 私钥和本脚本,4 个文件放在同一目录下
3. 在此脚本的分割线内写入相应的内容
4. 开启系统的 selinux
5. 给此脚本添加执行权限
6. 执行此脚本:./<执行本脚本>
脚本分割线里的变量
1. webdomain=”eternalcenter.com” #网站的域名,注意不要在前面加任何前缀
2. webtar=”eternalcenter-backup-*.tar.gz” #网站的网页数据备份,如果没有这个备份,可以下载一个开源的 WordPress 网页程序
3. webcrt=”eternalcenter.com.crt” #网站 SSL 的公钥,可以自己创建也可以在 FreeSSl 上申请
4. webkey=”eternalcenter.com.key” #网站 SSL 的私钥,可以自己创建也可以在 FreeSSL 上申请
5. sqlbackup=”eternalcenter-backup-*.sql” #网站数据库数据备份,如果没有这个备份(数据库是全量备份),则这里可以为空
6. db=”ec” #网站在数据库中库
7. dbuser=”ec” #网站在数据库中的用户
8. dbuserpw=”eternalcenter” #网站在数据库中的用户密码
9. dbrootpw=”eternalcenter” #数据库的 root 密码
注意
1. 服务器的系统需要是 openSUSE 15 版本
2. 服务器系统要配置好可用的软件源(最好是软件数量最多的官方版本)
3. 服务器要能够连接外网
脚本
#!/bin/bash
####################### Separator ########################
webdomain="eternalcenter.com"
webtar="eternalcenter-backup-*.tar.gz"
webcrt="eternalcenter.com.crt"
webkey="eternalcenter.com.key"
sqlbackup="eternalcenter-backup-*.sql"
db="ec"
dbuser="ec"
dbuserpw="eternalcenter"
dbrootpw="eternalcenter"
####################### Separator ########################
#判断所需文件是否存在
ls $webtar
if [ $? -ne 0 ];then
echo "没有网页数据备份,无法继续"
exit 2
fi
ls $webcrt
if [ $? -ne 0 ];then
echo "没有网站公钥,无法继续"
exit 2
fi
ls $webkey
if [ $? -ne 0 ];then
echo "没有网站私钥,无法继续"
exit 2
fi
#更新系统
zypper ref
zypper -n update
#确保必需软件已经安装
zypper -n in tar
zypper -n in firewalld
#部署 Nginx
zypper -n in nginx
echo 'worker_processes 1;
events {
worker_connections 1024;
}
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 60;
client_body_timeout 20s;
client_header_timeout 10s;
send_timeout 30s;
server {
listen 80;
limit_req zone=one burst=5;
server_name www.eternalcenter.com eternalcenter.com;
rewrite ^/(.*)$ https://eternalcenter.com/$1 permanent;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
listen 443 ssl;
server_name www.eternalcenter.com eternalcenter.com;
if ($request_method !~ ^(GET|POST)$){
return 444;
}
ssl_certificate /etc/nginx/ssl/eternalcenter.com.crt;
ssl_certificate_key /etc/nginx/ssl/eternalcenter.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
root /srv/www/htdocs;
location / {
index index.php;
try_files $uri $uri/ /index.php$is_args$args;
if (-f $request_filename/index.html){rewrite (.) $1/index.html break;}
if (-f $request_filename/index.php){rewrite (.) $1/index.php;}
if (!-f $request_filename){rewrite (.) /index.php;}
}
location ~ \.php$ {
include fastcgi_params;
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /srv/www/htdocs/$fastcgi_script_name;
}
location ~ ^/\.user\.ini {
deny all;
}
location ~*\.(jpd|jpeg|gif|png|css|js|ico|xml)$ {
expires 30d;
}
error_page 404 /404.html;
}
gzip on;
gzip_min_length 1000;
gzip_comp_level 4;
gzip_types text/plain test/css application/json application/x-javascript text/xml application/xml
application/xml+rss text/javascripts;
client_header_buffer_size 1k;
open_file_cache_valid 60s;
open_file_cache_min_uses 5;
open_file_cache_errors off;
}' > /etc/nginx/nginx.conf
sed -i "s/server_name www.eternalcenter.com eternalcenter.com;/server_name www.$webdomain $webdomain;/" /etc/nginx/nginx.conf
sed -i "s@rewrite ^/(.*)$ https://eternalcenter.com/\$1 permanent@rewrite ^/(.*)$ https://$webdomain/\$1 permanent@" /etc/nginx/nginx.conf;
sed -i "s/eternalcenter.com.crt/$webcrt/" /etc/nginx/nginx.conf
sed -i "s/eternalcenter.com.key/$webkey/" /etc/nginx/nginx.conf
mkdir /etc/nginx/ssl
mv $webcrt /etc/nginx/ssl
mv $webkey /etc/nginx/ssl
rm -rf /srv/www/htdocs/*
tar -xvf $webtar -C /srv/www/htdocs/ && rm -rf $webtar
zypper -n in policycoreutils
systemctl start nginx
systemctl enable nginx
#部署 MariaDB
zypper -n in mariadb mariadb-server
grep "^log_bin=" /etc/my.cnf
if [ $? -ne 0 ];then
sed -i '/^datadir/a log_bin=ec' /etc/my.cnf
fi
grep "^binlog_format=" /etc/my.cnf
if [ $? -ne 0 ];then
sed -i '/^datadir/a binlog_format=\"mixed\"' /etc/my.cnf
fi
grep "^server_id=" /etc/my.cnf
if [ $? -ne 0 ];then
sed -i '/^datadir/a server_id=51' /etc/my.cnf
fi
sed -i 's/^plugin-load-add=auth_gssapi.so/#plugin-load-add=auth_gssapi.so/' /etc/my.cnf
sed -i '/^user=.*/d' /etc/my.cnf
sed -i "/\[mysqld\]/a user=mysql" /etc/my.cnf
sed -i '/^bind-address=.*/d' /etc/my.cnf
sed -i "/\[mysqld\]/a bind-address=127.0.0.1" /etc/my.cnf
systemctl start mariadb
systemctl enable mariadb
chown -R mysql:mysql /var/lib/mysql
ls $sqlbackup
if [ $? -ne 0 ];then
mysql -uroot -e "create database $db;"
mysql -uroot -e "create user \"$dbuser\"@\"localhost\" identified by \"$dbuserpw\";"
mysql -uroot -e "grant all privileges on $db.* to \"$dbuser\"@\"localhost\" identified by \"$dbuserpw\";"
mysql -uroot -e "set password for 'root'@'localhost'=password(\"$dbrootpw\")"
else
mysql -uroot -e "create database $db;"
mysql -uroot $db < $sqlbackup
mysql -uroot -e "create user \"$dbuser\"@\"localhost\" identified by \"$dbuserpw\";"
mysql -uroot -e "grant all privileges on $db.* to \"$dbuser\"@\"localhost\" identified by \"$dbuserpw\";"
mysql -uroot -e "set password for 'root'@'localhost'=password(\"$dbrootpw\")"
rm -rf $sqlbackup
fi
systemctl restart mariadb
#部署 PHP
zypper -n in php7 php7-fpm php7-mysql php7-gd php7-mbstring php7-opcache php7-json php7-xmlrpc php7-zlib
useradd php-fpm -s /sbin/nologin
groupadd php-fpm
chown -R php-fpm:php-fpm /srv/www/htdocs
cp /etc/php7/fpm/php-fpm.conf.default /etc/php7/fpm/php-fpm.conf
sed -i /"^user =.*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^group =.*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^listen =.*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^[www]"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^pm = .*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^pm.start_servers = .*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^pm.min_spare_servers = .*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^pm.max_spare_servers = .*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^pm.max_children = .*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^pm.max_requests = .*"/d /etc/php7/fpm/php-fpm.conf
sed -i /"^request_terminate_timeout = .*"/d /etc/php7/fpm/php-fpm.conf
echo '[www]' >> /etc/php7/fpm/php-fpm.conf
echo 'user = php-fpm' >> /etc/php7/fpm/php-fpm.conf
echo 'group = php-fpm' >> /etc/php7/fpm/php-fpm.conf
echo 'listen = 127.0.0.1:9000' >> /etc/php7/fpm/php-fpm.conf
echo 'pm = dynamic' >> /etc/php7/fpm/php-fpm.conf
echo 'pm.start_servers = 2' >> /etc/php7/fpm/php-fpm.conf
echo 'pm.min_spare_servers = 2' >> /etc/php7/fpm/php-fpm.conf
echo 'pm.max_spare_servers = 4' >> /etc/php7/fpm/php-fpm.conf
echo 'pm.max_children = 4' >> /etc/php7/fpm/php-fpm.conf
echo 'pm.max_requests = 1024' >> /etc/php7/fpm/php-fpm.conf
echo 'request_terminate_timeout = 300' >> /etc/php7/fpm/php-fpm.conf
systemctl start php-fpm
systemctl enable php-fpm
#提高系统性能
grep "^* soft nofile" /etc/security/limits.conf
if [ $? -ne 0 ];then
echo '* soft nofile 1024' >> /etc/security/limits.conf
fi
grep "^* hard nofile" /etc/security/limits.conf
if [ $? -ne 0 ];then
echo '* hard nofile 1024' >> /etc/security/limits.conf
fi
#打开防火墙
systemctl start firewalld
systemctl enable firewalld
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload
#限制日志占用空间
echo "/var/log/mariadb/mariadb.log {
create 600 mysql mysql
notifempty
daily
rotate 3
missingok
compress
postrotate
# just if mysqld is really running
if [ -e /run/mariadb/mariadb.pid ]
then
kill -1 $(</run/mariadb/mariadb.pid)
fi
endscript
}" > /etc/logrotate.d/mariadb
echo "/var/log/nginx/*log {
create 0664 nginx root
size 1024M
rotate 1
missingok
notifempty
compress
sharedscripts
postrotate
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
endscript
}" > /etc/logrotate.d/nginx
echo "/var/log/php-fpm/*log {
size 100M
rotate 1
missingok
notifempty
sharedscripts
delaycompress
postrotate
/bin/kill -SIGUSR1 `cat /run/php-fpm/php-fpm.pid 2>/dev/null` 2>/dev/null || true
endscript
}" > /etc/logrotate.d/php-fpm
echo "/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
size 100M
rotate 1
missingok
sharedscripts
postrotate
/usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
endscript
}" > /etc/logrotate.d/syslog
#删除此脚本
scriptwhere=`readlink -f "$0"`
rm -rf $scriptwhere
#重启系统
reboot
[实验] Django 数据的显示 (通过自带应用 admin 实现) (SQLite 版)
注意:
文中的 python 系统名、mysite 项目、users 应用和 user 类只是站主在本次操作中随意取的名称,读者可以根据自己的喜好换成任意别的名称
正文:
步骤一:系统环境要求
1) 服务器的系统需要是 openSUSE 15.2 版本
2) 服务器要关闭防火墙
3) 服务器系统要配置好可用的软件源(最好是软件数量最多的官方版本)
4) 服务器要能够连接外网
步骤二:安装 Django
2.1 安装 Python3
[root@python ~]# zypper -n install python3
(补充:在此次操作发生时,最新的 python 版本是 3.6.12)
2.2 创建并进入 Django 项目的目录
[root@python ~]# mkdir project
[root@python ~]# cd project
2.3 将 Django 项目的目录指定为 Django 环境
[root@python project]# python3 -m venv django_env
2.4 进入 Django 环境
[root@python project]# source django_env/bin/activate
(django_env) [root@python project]# pip install django
(补充:在此次操作发生时,最新的 Django 版本是 3.2)
步骤三:创建 mysite 项目
3.1 创建 mysite 项目
(django_env) [root@python project]# django-admin startproject mysite
3.2 mysite 项目的目录
3.2.1 安装 tree 目录显示软件
(django_env) [root@python project]# zypper -n install tree
3.2.2 显示 mysite 项目的目录
(django_env) [root@python project]# cd mysite
(django_env) [root@python mysite]# tree
.
├── manage.py
└── mysite
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
1 directory, 5 files
3.2.3 Django 项目目录介绍
1) mysite 此 Django 项目的容器
2) manage.py 命令行工具,与 Django 项目进行交互
3) mysite/__init__.py 空文件,通知 Python 此项目是 1 个 Python 包
4) mysite/settings.py 此 Django 项目的配置文件
5) mysite/urls.py 此 Django 项目的 URL 声明和 Django 的网站“目录”
6) mysite/wsgi.py WSGI 兼容 Web 服务器的入口
步骤四:创建 users 应用
4.1 创建 users 应用
(django_env) [root@python mysite]# django-admin startapp users
4.2 users 应用的目录
4.2.1 显示 users 应用的目录
(django_env) [root@python mysite]# tree
.
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── users
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
3 directories, 13 files
4.2.2 Django 应用目录介绍
1) users/app.py 此 Django 应用的容器
2) users/__init__.py 空文件,通知 python 此项目是 1 个 python 包
3) users/admin.py 此 Django 应用自带的后台管理相关的类
4) users/app.py 此 Django 应用指定应用名的文件
5) users/migrations.py 此 Django 应用通过 python 代码生成数据库表时里面会产生一些迁移文件
6) users/models.py 可以在里面创建一些 Python 对象并通过这些对象在数据库里创建对应的表
7) users/test.py 此 Django 应用的测试文档
8) users/views.py 此 Django 应用的视图,接收前端数据,把数据传递给后端,响应相关页面
步骤五:实现注册功能
5.1 在 users 应用数据库模板中添加 users 类
在 mysite/users/models.py 中添加以下内容:
......
class user(models.Model):
tname = models.CharField(max_length=30,unique=True)
tpassword = models.CharField(max_length=30)
(
补充:
1) 这里以创建 tname 和 tpassword 两个字符,长度为 30 个字节,其中一个为唯一为例
2) 主键可以不用设置,默认会自动生成一个 ID 主键
3) 默认表名会生成 <应用名>_<模型类名>,在这里就是 users_user
4) 指定要生成的表名的设置方法是:
class Meta:
db_table = '<table name>'
)
5.2 在 users 应用中添加一个 html 模板
创建 mysite/users/templates/users/register.html 并添加以下内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>register</title>
</head>
<body>
<form action="/users/register/" method="post">
{% csrf_token %}
<p>
<label for="un">User: </label><input type="text" name="uname" id="un"/>
</p>
<p>
<label for="up">Password: </label><input type="password" name="upassword" id="up"/>
</p>
<input type="submit" value="register"/>
</form>
</body>
</html>
(
补充:这里以
1) 生成一个用户名输入栏,赋值给 uname
2) 生成一个密码输入栏,赋值给 upassword
3) 生成一个 register 提交按钮
为例
)
5.3 在 users 应用中添加一个网页返回值的模块并将符合的数值插入数据库
将 mysite/users/views.py 里的内容全部修改如下:
from django.shortcuts import render
from django.shortcuts import HttpResponse
from .models import user
# Create your views here.
def register(request):
if request.method=="GET":
return render(request,'users/register.html')
else:
uname = request.POST.get('uname','')
upassword = request.POST.get('upassword','')
if uname.strip()!='' and upassword.strip()!='':
# confirm whether uname and upassword are null
nuser = user(tname=uname,tpassword=upassword)
nuser.save()
return HttpResponse('success!')
else:
return HttpResponse('fail')
return HttpResponse('fail')
(
补充:这里以
1) 设置 register 模块并返回 users/register.html
2) 设置 register 模块当网页返回模式是 POST 且 uname 和 upassword 都为非空时将数据存入数据库
为例
)
5.4 在 users 应用中添加一个链接并设置对应的模块
创建 mysite/users/urls.py 并添加以下内容:
#coding=utf-8
from django.conf.urls import url
from users.views import register
urlpatterns = [
url(r'^register', register),
]
(补充:这里以设置 register 链接对应 register 模块为例)
5.5 在 mysite 应用中添加一个链接并链接 users 的链接
创建 mysite/users/urls.py 并添加以下内容:
......
#coding=utf-8
from django.conf.urls import url, include
from users.views import register
urlpatterns = [
......
url(r'^users/', include('users.urls')),
]
5.6 在 mysite 应用中导入 users 应用
在 mysite/mysite/settings.py 中添加以下内容:
INSTALLED_APPS = [
......
'users',
]
5.7 将 Django 的模板导入 SQLite 数据库
5.7.1 生成牵引文件
(django_env) [root@python mysite]# python3 manage.py makemigrations
Migrations for 'users':
users/migrations/0001_initial.py
- Create model user
(补充:这里以将 users 应用的 model 模块转换成牵引文件为例)
5.7.2 将牵引文件导入 SQLite 数据库
(django_env) [root@python mysite]# python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, users
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
Applying users.0001_initial... OK
步骤六:在 admin 应用中添加数据展示
6.1 在 users 应用数据库模板中添加显示数据的配置
在 mysite/users/models.py 中添加以下内容:
......
def __str__(self):
return u'users:%s'%self.tname
(
补充:
1) 这里以将 user 类里的 tname 字段以 users:<tname value> 的列表形式显示为例
2) u 在 return u’users:%s’%self.tname 里代表正则的意思
)
6.2 在 Django 应用的 admin 应用中导入数据库模版中的 user 类
在 mysite/users/admin.py 中添加以下内容:
......
from .models import user
admin.site.register(user)
(补充:这里以导入 models 的 user 类为例)
6.3 设置 admin 应用的语言和时区
在 mysite/mysite/settings.py 中将以下内容:
......
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
......
修改为:
......
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
......
(补充:这里设置语言为汉语,时区为上海为例)
6.4 创建 admin 应用的用户
(django_env) [root@python mysite]# python3 manage.py createsuperuser
Username (leave blank to use 'root'): eternalcenter
Email address: eternalcenter@eternalcenter.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
步骤七:启动 Django 服务
(django_env) [root@python mysite]# python3 manage.py runserver
步骤八:测试注册功能
1) 打开浏览器输入以下网址:
http://127.0.0.1:8000/users/register/
2) 当用户名输入 eternalcenter,密码输入密码 1 点击 “register” 时,返回 successful
步骤九:使用 admin 模块显示 SQLite 数据库里的数据
1) 打开网页:
http://127.0.0.1:8000/admin/
2) 使用创建的 admin 模块的用户登录
3) 点击 “Users”
4) 可以看到一条 users:eternalcenter 的数据