一、任务
- 修改添加标签接口:由于添加标签的接口用起来比较麻烦,因而需要进行改进
- 添加文件上传接口
二、修改添加标签接口
1.接口输入输出设计
原来
之前的修改文章接口设计是:
方式 | url | 功能 |
---|---|---|
… | … | … |
post | /blog/articles/<pk>/article_op_tag/ | * 为指定文章添加列表中的标签 |
delete | /blog/articles/<pk>/article_op_tag/ | * 为指定文章删除列表中的标签 |
接受的json数据
{
"tag_ids": [标签id, "标签名", ...]
}
改进
方式 | url | 功能 |
---|---|---|
… | … | … |
post | /blog/articles/<pk>/article_op_tag/ | * 为指定文章添加或删除列表中的标签 |
接受的json数据
{
"tag_ids": [标签id, "标签名", ...]
}
具体的功能是:如果输入的数组中的某个元素是字符串,则创建对应的标签后为文章添加该标签,其他情况则与文章原标签进行对比(集合的相减操作),如A是改动后的标签(包含1,2标签),B是原有标签(包含2,3),则A-B即可获得新增标签集合,B-A可获得删除的标签集合,然后分别创建和删除A-B中和B-A中的标签即可。
2.代码实现
class ArticleViewSet(ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
@action(methods=['POST'], detail=True)
def article_op_tag(self, request, pk):
article = self.get_object()
data = request.data
"""
{tag_id: 2}
"""
tag_ids = data['tag_ids']
tags_id_list = []
tags_str_list = []
for tag_id in tag_ids:
if isinstance(tag_id, str):
tags_str_list.append(tag_id)
else:
tags_id_list.append(tag_id)
origin_tags_id = []
article_tags = article.article_tags.all()
for tag in article_tags:
origin_tags_id.append(tag.id)
new_id_list = list(set(tags_id_list) - set(origin_tags_id)) # A-B
for tag_str in tags_str_list:
new_tag = TagOfArticle.objects.create(tag_name=tag_str)
new_id_list.append(new_tag.id)
delete_id_list = list(set(origin_tags_id)-set(tags_id_list)) # B-A
# 创建和删除
for tag_id in new_id_list:
tag = get_object_or_404(TagOfArticle, pk=tag_id)
article.article_tags.add(tag)
for tag_id in delete_id_list:
tag = get_object_or_404(TagOfArticle, pk=tag_id)
article.article_tags.remove(tag)
serializer = ArticleSerializer(instance=article)
return Response(serializer.data)
这样即可实现任意修改的功能了。
三、添加文件上传接口
参考博客:http://www.beiliangshizi.com/?p=811
接口设计
url | 功能 |
---|---|
/file/upload | 上传文件 |
接受的数据格式
{
file: 文件
remark: "附带信息"
}
1. 修改settings.py
在末尾添加
...
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
2. 新建app并定义模型(file_app)
> manage.py startapp file_app
然后添加到settings.py中
(主路由的设置比较基本,这里不赘述)
模型:
from django.db import models
from backend.utils.models import BaseModel
class File(BaseModel):
file = models.FileField(blank=False, null=False)
remark = models.CharField(max_length=20)
序列化器
from rest_framework import serializers
from .models import File
class FileSerializer(serializers.ModelSerializer):
class Meta:
model = File
fields = '__all__'
视图
视图是直接cv参考链接的博主的,有很多东西也不清楚…
from rest_framework import viewsets
from .models import File
from .serializer import FileSerializer
class FileViewSet(viewsets.ModelViewSet):
queryset = File.objects.all()
serializer_class = FileSerializer
最后是路由:
from rest_framework import routers
from .views import FileViewSet
urlpatterns = [
]
router = routers.DefaultRouter()
router.register(r'upload', FileViewSet, basename='upload')
urlpatterns += router.urls
这样文件上传功能就已经实现了。
使用postman测试:
返回的信息:
{
"id": 1,
"create_time": "2021-04-26T08:20:59.091949Z",
"update_time": "2021-04-26T08:20:59.091949Z",
"file": "/media/Snipaste_2021-04-26_16-20-30.png",
"remark": "第一个文件"
}
在项目/media目录下:
成功接收到了上传的图片文件。
使在外部可以通过url访问到图片
参考博客:https://www.jb51.net/article/184200.htm
修改主路由即可:
...
from django.urls import ..., re_path <---
from django.views.static import serve <---
from . import settings <---
urlpatterns = [
re_path(r'media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}), <---
...
]
效果:
上一步:Vue+DRF搭建博客之前端篇(四)
下一步:Vue+DRF搭建博客之前端篇(五)