task04 and task05

This commit is contained in:
Tomo Wang 2021-04-28 20:14:47 +08:00
parent 24837acd07
commit 29b0505e1a
8 changed files with 183 additions and 1 deletions

View File

@ -21,4 +21,14 @@ class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = ('id', 'email', 'phone', 'nickname', 'date_joined', 'last_login', 'last_login_ip', 'description', 'groups')
fields = (
'id',
'email',
'phone',
'nickname',
'date_joined',
'last_login',
'last_login_ip',
'description',
'groups',
)

BIN
images/task04-api-error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
images/task04-migrate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

169
task04.md Normal file
View File

@ -0,0 +1,169 @@
# 前言
本节课程,你将依照在[task02](./task02.md)中编写的用户管理接口规范,实现用户管理相关后端接口及前端界面。
# 后端接口相关
该章节你将学习实现接口所涉及的代码。
## Model & Migrate
在[task01](./task01.md)课程中,你已熟悉`User`这个Model类。按照需求需要扩展用户相关属性。
如期望增加学校字段`school`,可以在`User`该类中添加相关属性(文件路径`bluewhale/core/models.py`
```python
# 已定义属性
school = models.CharField(_('school'), max_length=64, blank=True)
objects = UserManager()
```
保存文件后,你将能看到命令行中展示如下信息:
![django reload](./images/task04-django-reload.png)
该信息表明Django识别到文件发生变动并重新加载了变动。这时再次访问接口
[http://127.0.0.1:8000/api/v1/me](http://127.0.0.1:8000/api/v1/me)将会看到如下错误信息:
![api error](./images/task04-api-error.png)
这是因为我们新增了字段,但是还没有处理数据。通过`Ctrl+C`停掉后端接口进程,然后执行下面命令可以处理数据库相关事项:
* `python manage.py makemigrations` - 生成migration脚本
* `python manage.py migrate` - 执行migration脚本
执行结果如下:
![migrate](./images/task04-migrate.png)
生成的migration脚本可以在app目录下面的migrations文件夹中找到如下
![db after migration](./images/task04-db-after-migration.png)
至此数据库相关的修改已完成。
## Serializer
通过`python manage.py runserver`重新启动服务后,再次访问
[http://127.0.0.1:8000/api/v1/me](http://127.0.0.1:8000/api/v1/me),会发现结果中
并没有`school`属性:
```json
{
"data": {
"id": 1,
"email": "admin@example.com",
"phone": "",
"nickname": "",
"date_joined": "2021-01-25T03:28:09.214616Z",
"last_login": "2021-04-27T06:22:06.690042Z",
"last_login_ip": "127.0.0.1",
"description": "",
"groups": []
},
"code": 0
}
```
原因是我们还需处理序列化相关的代码,增加这部分的序列化配置。文件路径为`bluewhale/core/serializers.py`
类为`UserSerializer`。通过定义该类中`Meta`类的`fields`属性,我们可以添加我们需要序列化的字段。
添加`school`项,并刷新页面[http://127.0.0.1:8000/api/v1/me](http://127.0.0.1:8000/api/v1/me)
观察返回的结果数据。
至此序列化相关的修改已完成。
## APIView & URL
要新增用户管理相关后端接口实现,我们需要创建`APIView`并在`urls.py`中添加URL路由至APIView的映射。
`APIView`是一种特殊的类Django将REST接口相关的增删改查的操作(HTTP Method)映射为`APIView`类中对应的方法:
* 查询列表或单个数据项 - `get -> retrieve`
* 新增 - `post -> create`
* 修改 - `put -> update` & `patch -> partial_update`
* 删除 - `delete -> destroy`
如果需要对特定的接口做特殊的处理,可以通过`Override`实际处理函数进行处理,具体示例可以参考`bluewhale/blog/views.py`
中的处理该示例中使用非自增的id作为主键而是使用生成uuid的方式作为主键
```python
class ArticleListCreateView(BasicListCreateAPIView):
permission_classes = [IsAuthenticated|ReadOnly]
serializer_class = ArticleSerializer
queryset = Article.objects.all()
def create(self, request, *args, **kwargs):
data = request.data
data['id'] = shortuuid.uuid()
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(
{
'data': serializer.data,
'code': 0,
},
status=status.HTTP_201_CREATED, headers=headers
)
def perform_create(self, serializer):
serializer.save(author=self.request.user)
class ArticleDetailView(BasicRetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticated|ReadOnly]
serializer_class = ArticleSerializer
queryset = Article.objects.all()
```
最后在`bluewhale/bluewhale/urls.py`中对所要的接口路径进行URL与APIView的映射
```python
path(f'{api_prefix}/articles', ArticleListCreateView.as_view(), name='articles'),
path(f'{api_prefix}/articles/<pk>', ArticleDetailView.as_view(), name='article'),
```
至此接口及View处理完毕。
# 服务端部署
在本次课程中,我们需要将我们编写的代码上传至服务端并运行(服务器用户及密码等信息由助教提供)。
## 同步后端代码
在clone的项目根目录运行如下命令
```shell
export USER=team00 # 替换成助教提供的用户名
export HOST=127.0.0.1 # 替换成助教提供的服务器地址
rsync -avzh --delete --exclude=*.pyc --exclude=.venv --exclude=.idea --exclude=.env \
--exclude=.git --exclude=__pycache__ \
bluewhale $USER@$HOST:
```
该命令将后端代码目录同步至远程服务器中。登录到远程服务器,在用户主目录下将看到`bluewhale`文件夹,
其中为后端代码。参考课程[task00](./task00.md)中环境搭建-后端服务的部分初始化后端项目db及用户。
最终运行时,指定监听的端口(**端口号由助教提供**
```shell
python manage.py runserver 127.0.0.1:8800
```
## 同步前端代码
在clone的项目子目录`client`,编译前端文件,然后同步至服务端:
```shell
npm run build # 编译前端代码
export USER=team00 # 替换成助教提供的用户名
export HOST=127.0.0.1 # 替换成助教提供的服务器地址
rsync -avzh dist $USER@$HOST:/usr/share/caddy/$USER
```
该命令将编译后的前端代码目录`dist`同步至远程服务器中。
部署完成后,打开浏览器输入服务器地址,你将能看到实现的界面。

3
task05.md Normal file
View File

@ -0,0 +1,3 @@
# 前言
本节课程,你将依照在[task02](./task02.md)中编写的赛事管理接口规范,实现赛事管理相关后端接口及前端界面。