0 背景
完成datawhale的web入门开发task02的学习:
https://github.com/datawhalechina/whale-web/blob/master/task02.md
task02内容如下:
用户管理
通过上节课程,你已大概了解Django中现有的接口与Model及后端DB呈现,并能看到用户相关的接口,包括:
注册 - register
登录 - login
登出 - logout
个人信息 - me
本节课程你需要扩展用户相关属性,并定义用户管理相关接口。
用户属性界面:
user profile
需要基于现有的用户属性,扩充表单中要求的额外属性,如头像、学校、专业等。
编辑openapi.yaml中components.schemas.User
新增用户增删改查接口文档
实现步骤
- Step1:在core 里面编辑model.py
- Step2:在urls.py写接口
- Step3:在view_auth.py,添加具体实现
- Step4: 更新前端open_api.yaml
注释:代码更新添加部分见下方彩色字体黑框显示部分
Step1:在core 里面编辑model.py
from django.db import models
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser
from django.utils import timezone
from django.core.mail import send_mail
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from .managers import UserManager
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
phone = models.CharField(_('phone'), max_length=30, blank=True, unique=True, null=True)
nickname = models.CharField(_('nickname'), max_length=150, blank=True)
user_img = models.CharField(max_length=255,verbose_name='头像',default='')
wx_num = models.CharField(max_length=50,verbose_name='微信号',default='')
school = models.CharField(max_length=255,verbose_name='学校',default='')
major = models.CharField(max_length=255,verbose_name='专业',default='')
gs = models.CharField(max_length=255,verbose_name='公司',default='')
zw = models.CharField(max_length=255,verbose_name='职位',default='')
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_('Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'),
)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
description = models.TextField(_('description'), blank=True)
last_login_ip = models.CharField(_('last login ip'), max_length=64, blank=True)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
def clean(self):
super().clean()
self.email = self.__class__.objects.normalize_email(self.email)
def email_user(self, subject, message, from_email=None, **kwargs):
"""Send an email to this user."""
send_mail(subject, message, from_email, [self.email], **kwargs)
Step2:在urls.py写接口
新增用户增删改查接口文档
from django.urls import include, path
from django.contrib.auth import get_user_model
from rest_framework import routers
from rest_auth.views import LogoutView
from core.views_auth import BluewhaleLoginView, get_user_info,\
add_user_info,del_user_info,update_user_info,\
send_verification_mail,\
verify_verification_token,\
register
from blog.views import ArticleListCreateView, ArticleDetailView
from rest_framework import routers
api_prefix = 'api/v1'
router = routers.DefaultRouter()
urlpatterns = [
# path('admin/', admin.site.urls),
path(f'{api_prefix}/login', BluewhaleLoginView.as_view(), name='rest_login'),
path(f'{api_prefix}/logout', LogoutView.as_view(), name='rest_logout'),
path(f'{api_prefix}/send-verification', send_verification_mail, name='send verification mail'),
path(f'{api_prefix}/verify/<token>', verify_verification_token, name='verify verification token'),
path(f'{api_prefix}/register', register, name='register'),
path(f'{api_prefix}/me', get_user_info, name='user profile'),
path(f'{api_prefix}/me/add', add_user_info, name='user profile'),
path(f'{api_prefix}/me/delete', del_user_info, name='user profile'),
path(f'{api_prefix}/me/update', update_user_info, name='user profile'),
path(f'{api_prefix}/articles', ArticleListCreateView.as_view(), name='articles'),
path(f'{api_prefix}/articles/<pk>', ArticleDetailView.as_view(), name='article'),
path(f'{api_prefix}/', include(router.urls)),
]
Step3:在view_auth.py,添加具体实现
(backend) bash-3.2$ cd backend/
(backend) bash-3.2$ python manage.py runserver
成功后显示如下:
System check identified 1 issue (0 silenced).
May 16, 2021 - 14:08:22
Django version 3.2, using settings 'bluewhale.settings'
Starting development server at http://127.0.0.1:8000/
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/
Using the URLconf defined in bluewhale.urls, Django tried these URL patterns, in this order:
1. api/v1/login [name='rest_login']
2. api/v1/logout [name='rest_logout']
3. api/v1/send-verification [name='send verification mail']
4. api/v1/verify/<token> [name='verify verification token']
5. api/v1/register [name='register']
6. api/v1/me [name='user profile']
7. api/v1/me/add [name='user profile']
8. api/v1/me/delete [name='user profile']
9. api/v1/me/update [name='user profile']
10. api/v1/articles [name='articles']
11. api/v1/articles/<pk> [name='article']
12. api/v1/
The empty path didn’t match any of these.
You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
Step4: model添加user字段后同步到数据库
(注意:开始写前端,上面是后端的,现在开始写openAPI.yaml代码,注意上面view里面的具体实现内容我们没有写,但不影响效果展示,有需要的小伙伴可自行补充)
找到backend,找到models.py,找到user,启动命令行,找到manage.py的目录,运行命令:
1) 先执行python manage.py makemigrations
这一步骤生成了一个文件,但数据库里面还没有
core/migrations/0003_auto_20210516_1351.py
- Add field gs to user
- Add field major to user
- Add field school to user
- Add field user_img to user
- Add field wx_num to user
- Add field zw to user
2) 再执行python manage.py migrate,数据同步到数据库了;
运行成功后输出:
Operations to perform:
Apply all migrations: auth, authtoken, blog, contenttypes, core, sessions
Running migrations:
Applying core.0003_auto_20210516_1351... OK
3)再去数据库里面查看表,及字段,可以看到添加的major等字段都已经在表中:
/usr/local/mysql/bin/mysql -u bluewhale -p bluewhale
mysql> desc core_user;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| password | varchar(128) | NO | | NULL | |
| last_login | datetime(6) | YES | | NULL | |
| is_superuser | tinyint(1) | NO | | NULL | |
| email | varchar(254) | NO | UNI | NULL | |
| phone | varchar(30) | YES | UNI | NULL | |
| nickname | varchar(150) | NO | | NULL | |
| is_active | tinyint(1) | NO | | NULL | |
| date_joined | datetime(6) | NO | | NULL | |
| description | longtext | NO | | NULL | |
| last_login_ip | varchar(64) | NO | | NULL | |
| gs | varchar(255) | NO | | NULL | |
| major | varchar(255) | NO | | NULL | |
| school | varchar(255) | NO | | NULL | |
| user_img | varchar(255) | NO | | NULL | |
| wx_num | varchar(50) | NO | | NULL | |
| zw | varchar(255) | NO | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
17 rows in set (0.00 sec)
step5 前端openapi.yaml文档
openapi: 3.0.3
info:
title: Bluewhale
description: 'This is API specifications for bluewhale site'
version: 1.0.0
servers:
- url: http://127.0.0.1:4010
paths:
"/api/v1/me":
get:
summary: get current user's profile
responses:
'200':
description: current user
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/User"
code:
type: integer
"/api/v1/me/add":
post:
summary: add current user's profile
responses:
'200':
description: current user
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/User"
code:
type: integer
"/api/v1/me/delete":
post:
summary: delete current user's profile
responses:
'200':
description: current user
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/User"
code:
type: integer
"/api/v1/me/update":
post:
summary: add current user's profile
responses:
'200':
description: current user
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/User"
code:
type: integer
"/api/v1/login":
options:
summary: get csrf token
responses:
'200':
description: options
post:
summary: login
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/LoginForm"
responses:
'200':
description: success login
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/User"
code:
type: integer
"/api/v1/logout":
post:
summary: logout
responses:
'200':
description: success logout
"/api/v1/send-verification":
post:
summary: send verification mail
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/SendVerificationForm"
responses:
'200':
description: success logout
content:
application/json:
schema:
type: object
properties:
data:
type: integer
code:
type: integer
"/api/v1/verify/<token>":
get:
summary: verify verification token
responses:
'200':
description: verify through email
content:
application/json:
schema:
type: object
properties:
data:
$ref: "#/components/schemas/VerifyForm"
code:
type: integer
"/api/v1/register":
post:
summary: register
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/RegisterForm"
responses:
'200':
description: success logout
content:
application/json:
schema:
type: object
properties:
data:
type: integer
code:
type: integer
"/api/v1/articles":
post:
summary: articles
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ArticlesForm"
responses:
'200':
description: Articles
content:
application/json:
schema:
type: object
properties:
data:
type: integer
code:
type: integer
"/api/v1/articles/<pk>":
post:
summary: articles
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/ArticlesPkForm"
responses:
'200':
description: Articles Pk
content:
application/json:
schema:
type: object
properties:
data:
type: integer
code:
type: integer
components:
schemas:
CommonResponse: # common response which has data and code properties
type: object
properties:
data:
type: object
code:
type: integer
LoginForm:
type: object
properties:
email:
type: string
format: email
password:
type: string
format: password
SendVerificationForm:
type: object
properties:
email:
type: string
format: email
VerifyForm:
type: object
properties:
email:
type: string
format: email
RegisterForm:
type: object
properties:
token:
type: string
format: token
ArticlesPkForm:
type: object
properties:
Pkid:
type: string
format: Pkid
title:
type: string
format: title
content:
type: string
format: content
ArticlesForm:
type: object
properties:
title:
type: string
format: title
content:
type: string
format: content
User:
type: object
properties:
id:
type: integer
format: int64
minimum: 1
email:
type: string
format: email
phone:
type: string
nickname:
type: string
user_img:
type: string
wx_num:
type: string
school:
type: string
major:
type: string
gs:
type: string
zw:
type: string
date_joined:
type: string
format: date-time
last_login:
type: string
format: date-time
last_login_ip:
type: string
format: ipv4
description:
type: string
groups:
type: array
items:
$ref: "#/components/schemas/Group"
Group:
type: object
properties:
id:
type: integer
format: int64
minimum: 1
name:
type: string