Django 基于DRF的列表增删改查

发布时间 2023-08-21 17:43:13作者: f_carey

基于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为名称,level_text随意。

    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):
    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宣告路由:方式二
]