Django 基于DRF的列表增删改查
基于DRF的列表增删改查
目录
1 表结构
from django.db import models
# Create your models here.
class Tag(models.Model):
caption = models.CharField(verbose_name='标签', max_length=32)
class Course(models.Model):
title = models.CharField(verbose_name='课程名称', max_length=32)
class Module(models.Model):
level_choices = (
(1, '初级'),
(2, '中级'),
(3, '高级'),
)
name = models.CharField(verbose_name="章节模块", max_length=32)
level = models.IntegerField(verbose_name="级别", choices=level_choices, default=1)
course = models.ForeignKey(verbose_name='课程', on_delete=models.CASCADE, to='Course')
class Video(models.Model):
title = models.CharField(verbose_name='视频名称', max_length=32)
vid = models.CharField(verbose_name='视频ID', max_length=32)
tag = models.ManyToManyField(verbose_name='标签', to='Tag',)
2 基于APIView实现对course表获取所有数据,增加数据
2.1 ser
from rest_framework import serializers
from api import models
class CourseSerializer(serializers.ModelSerializer):
class Meta:
model = models.Course
# 显示所有数据
fields = '__all__'
2.2 views
class CourseView(APIView):
"""
基于APIView实现对课程表的
- 获取所有数据
- 增加数据
"""
def get(self, request, *args, **kwargs):
queryset = models.Course.objects.all()
course_ser = ser.CourseSerializer(instance=queryset, many=True)
return Response(course_ser.data)
def post(self, request, *args, **kwargs):
"""
# 1.获取用户提交的数据 request.data
# 2.校验数据的合法性 序列化
# 3.校验通过save
# 4.不通过报错
:param request:
:param args:
:param kwargs:
:return:
"""
data = request.data
course_ser = ser.CourseSerializer(data=data)
if course_ser.is_valid():
course_ser.save()
return Response("ok")
return Response('...')
2.3 urls
urlpatterns = [
re_path(r'^course/$', views.CourseView.as_view()),
]
3 基于ListAPIView、CreateAPIView实现获取所有数据,增加数据
3.1 ser
from rest_framework import serializers
from api import models
class CourseSerializer(serializers.ModelSerializer):
class Meta:
model = models.Course
# 显示所有数据
fields = '__all__'
3.2 views
class CourseView2(ListCreateAPIView):
"""
基于ListAPIView、CreateAPIView实现
- 获取所有数据
- 增加数据
"""
queryset = models.Course.objects.all()
serializer_class = ser.CourseSerializer
class CourseView3(ListAPIView, CreateAPIView):
"""
基于ListAPIView、CreateAPIView实现
- 获取所有数据
- 增加数据
"""
queryset = models.Course.objects.all()
serializer_class = ser.CourseSerializer
3.3 urls
urlpatterns = [
re_path(r'^course2/$', views.CourseView2.as_view()),
re_path(r'^course3/$', views.CourseView3.as_view()),
]
4 基于ModelViewSet实现Course表实现增删改查
4.1 ser
from rest_framework import serializers
from api import models
class CourseSerializer(serializers.ModelSerializer):
class Meta:
model = models.Course
# 显示所有数据
fields = '__all__'
4.2 views
class CourseView4(ModelViewSet):
"""
基于ModelViewSet实现Course表实现增删改查
"""
queryset = models.Course.objects.all()
serializer_class = ser.CourseSerializer
4.3 urls
urlpatterns = [
re_path(r'^course4/(?P<pk>\d+)/$',
views.CourseView4.as_view({'get': 'retrieve', 'post': 'create', 'put': 'update', 'delete': 'destroy'})),
]
5 基于APIView+serializer实现对模块表 获取列表数据。FK
5.1 ser
class ModuleSerializer(serializers.ModelSerializer):
cname = serializers.CharField(source='course.title') # 显示course为名称,cname可为任意值
level_text = serializers.CharField(source='get_level_display') # 显示level为名称,注意:choice显示中文可以使用source字段 `"get_字段名_display"`
class Meta:
model = models.Module
# fields = '__all__' # 显示所有数据
# fields = ['id', 'name', 'course'] # 指定只显示id,name与course;course为fk,显示的为ID值
# fields = ['id', 'name', 'cname']# 显示course为名称,cname可为任意值,但要与serializers.CharField对应起来
# fields = ['id', 'name', 'level', 'cname'] # 增加存在选择选项的数据level,显示也是选项id值。
fields = ['id', 'name', 'level_text', 'cname'] # 显示level为名称。
5.2 views
class ModuleView(APIView):
"""
基于APIView+serializer实现对模块表 获取列表数据。FK
"""
def get(self, request, *args, **kwargs):
queryset = models.Module.objects.all()
module_ser = ser.ModuleSerializer(instance=queryset, many=True)
return Response(module_ser.data)
5.3 urls
urlpatterns = [
re_path(r'^module/$', views.ModuleView.as_view()),
]
6 基于ListAPIView等实现对module表单条数据展示,增加
6.1 ser
class ModuleSerializer2(serializers.ModelSerializer):
class Meta:
model = models.Module
fields = '__all__' # 显示所有数据
6.2 views
class ModuleView2(RetrieveAPIView, CreateAPIView):
"""
基于ListAPIView等实现对module表:单条数据展示、增加。
"""
queryset = models.Module.objects.all()
serializer_class = ser.ModuleSerializer2
6.3 urls
urlpatterns = [
re_path(r'^module2/(?P<pk>\d+)/$', views.ModuleView2.as_view()),
]
7 基于ModelViewset实现对Module表进行增删改查
7.1 ser
class ModuleSerializer2(serializers.ModelSerializer):
class Meta:
model = models.Module
fields = '__all__' # 显示所有数据
7.2 views
class ModuleView3(ModelViewSet):
"""
基于ModelViewset实现对Module表进行增删改查。
"""
queryset = models.Module.objects.all()
serializer_class = ser.ModuleSerializer2
def partial_update(self, request, *args, **kwargs):
pk = kwargs.get('pk')
module_object = models.Module.objects.filter(id=pk).first()
module_ser = ser.ModuleSerializer2(instance=module_object, data=request.data, many=False, partial=True)
if module_ser.is_valid():
module_ser.save()
return Response('成功')
return Response(module_ser.errors)
7.3 urls
urlpatterns = [
re_path(r'^module3/$', views.ModuleView3.as_view({'get': 'list', 'post': 'create'})),
re_path(r'^module3/(?P<pk>\d+)/$', views.ModuleView3.as_view(
{'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})),
]
8 对Video表做接口获取视频列表、单条视频信息,增删改查M2M
8.1 ser
class VideoSerializer(serializers.ModelSerializer):
"""
基于SerializerMethodField+自定义一个钩子方法。
"""
tag_name = serializers.SerializerMethodField()
class Meta:
model = models.Video
fields = ['id', 'title', 'vid', 'tag', 'tag_name']
def get_tag_name(self, obj): # 可以查看SerializerMethodField 源码看到
tag_list = obj.tag.all()
return [{'id': row.id, 'caption': row.caption} for row in tag_list]
8.2 views
class VideoView(ModelViewSet):
"""
对Video表做接口:
- 获取视频列表、单条视频信息。
- 增删改查(多对多操作tag名称)
"""
queryset = models.Video.objects.all()
serializer_class = ser.VideoSerializer
8.3 urls
from django.urls import path, re_path, include
from api import views
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'video', views.VideoView)
urlpatterns = router.urls # router宣告路由:方式一
# 方式二
urlpatterns = [
# re_path(r'^video/$', views.VideoView.as_view({'get': 'list', 'post': 'create'})),
# re_path(r'^video/(?P<pk>\d+)/$', views.VideoView.as_view(
# {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})),
re_path(r'^', include(router.urls)), # router宣告路由:方式二
]