首页 > 其他分享 >函数视图-类视图-mixins视图-通用视图-视图集

函数视图-类视图-mixins视图-通用视图-视图集

时间:2023-02-02 16:11:15浏览次数:47  
标签:return name models mixins 视图 图集 data class serializer

1.函数视图

@api_view(['get', 'post'])
def student_list_or_create(request, format=None):
    """
    学生列表,学生创建视图
    :param request:
    :return:
    """
    if request.method == 'GET':
        # 1. 拿到所有的对象
        objs = Student.objects.all()
        # 2. 序列化
        serializer = StudentSerializer(objs, many=True)
        # 3. 返回drf的响应
        return Response(serializer.data)
    elif request.method == 'POST':
        # 1. 创建序列化器对象
        serializer = StudentSerializer(data=request.data)
        # 2. 校验
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

#在视图函数里加关键字参数format,默认可浏览的api模式html(format=None)
@api_view(['get', 'put', 'delete'])
def student_detail_update_delete(request, pk, format=None):
    """
    学生详情,更新,删除视图
    :param request:
    :param pk:
    :return:
    """
    # 1. 获取对象
    obj = get_object_or_404(Student, pk=pk)

    # 2. 判断操作
    if request.method == 'GET':
        serializer = StudentSerializer(obj)
        return Response(serializer.data)
    elif request.method == 'PUT':
        # 创建序列化器
        # 应为是要更新对象,所以序列化器里需要传入data
        serializer = StudentSerializer(obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        obj.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

函数视图设置路由

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from . import views


urlpatterns = [
   # 添加到应用路由中
    path('students/', views.student_list_or_create, name='list_create'),
    path('students/<int:pk>/', views.student_detail_update_delete, name='detail_update_delete'),
]

# 处理一下路由,可以选择不同的渲染格式
urlpatterns = format_suffix_patterns(urlpatterns)

2.类视图

类视图和我们的django的类视图没有什么区别。

django类视图

from django.views import View

class StudentView(View):
    """
    学生视图
    """
    def get(self, request, pk=None):
        """
        学生列表、学生详情
        :param request:
        :param pk:
        :return:
        """
        if pk is None:
            # 学生列表
            # 1. 获取学生列表
            objs = Student.objects.all()
            # 2. 序列化
            # 使用序列化器序列化查询集
            serializer = StudentSerializer(objs, many=True)
            # 3.返回json响应
            return JsonResponse(data=serializer.data, safe=False)  #当data不是一个字典的时候,要加上safe=False
        else:
            # 学生详情
            # 1. 获取学生对象
            obj = get_object_or_404(Student, pk=pk)
            # 2. 序列化
            serializer = StudentSerializer(obj)
            # 3.返回json响应
            return JsonResponse(data=serializer.data)

    def post(self, request):
        """
        创建学生
        :param request:
        :return:
        """
        # 1. 接受数据转换为字典
        data = json.loads(request.body)
        # 创建序列化器
        serializer = StudentSerializer(data=data)
        # 2.校验
        if serializer.is_valid():
            serializer.save()
            # 校验成功返回创建对象的信息
            return JsonResponse(data=serializer.data, status=201)
        else:
            # 校验不成功返回错误信息
            return JsonResponse(data=serializer.errors, status=400)

    def put(self, request, pk):
        """
        修改学生
        :param request:
        :param pk:
        :return:
        """
        # 1. 获取对象
        obj = get_object_or_404(Student, pk=pk)
        # 2. 获取数据转换成字典
        data = json.loads(request.body)

        # 3. 创建序列化器
        serializer = StudentSerializer(instance=obj, data=data)
        # 4. 校验
        if serializer.is_valid():
            serializer.save()
            # 校验成功返回创建对象的信息
            return JsonResponse(data=serializer.data, status=200)
        else:
            # 校验不成功返回错误信息
            return JsonResponse(data=serializer.errors, status=400)

    def delete(self, request, pk):
        """
        删除学生
        :param request:
        :param pk:
        :return:
        """
        # 1. 获取对象
        obj = get_object_or_404(Student, pk=pk)

        # 2. 删除
        obj.delete()
        return HttpResponse(status=204)

路由设置

from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from rest_framework.routers import DefaultRouter
from . import views

urlpatterns = [
    
     path('students/', views.StudentView.as_view(), name='list_create'),
     path('students/<int:pk>/', views.StudentView.as_view(), name='detail_update_delete')
]

# 处理一下路由,可以选择不同的渲染格式
urlpatterns = format_suffix_patterns(urlpatterns)

drf类视图

from rest_framework.views import APIView

class CustomGenericApiView(APIView):
    # 视图使用的查询集
    queryset = None
    # 序列化器类
    serializer_class = None

    def get_queryset(self):
        if self.queryset is None:
            raise ValueError('必须设置一个queryset属性')

        queryset = self.queryset

        queryset = queryset.all()
        return queryset

    def get_serializer_class(self):
        if self.serializer_class is None:
            raise ValueError('必须设置一个serializer_class属性')
        return self.serializer_class

    def get_serializer(self, instance=None, data=empty, **kwargs):
        serializer_class = self.get_serializer_class()
        return serializer_class(instance, data, **kwargs)

3.mixins视图

import json

from django.shortcuts import (
    render, get_object_or_404, redirect,
    reverse
)
from django.views import View
from django.http.response import JsonResponse, HttpResponse

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status, generics, mixins
from rest_framework.views import APIView
from rest_framework.fields import empty
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet

from .models import Student, Channel, Course
from .serializers import StudentSerializer, CourseSerializer

class MixinListView:
    def get(self, request, format=None):
        # 1. 拿到所有的对象
        objs = self.get_queryset()
        # 2. 序列化
        serializer_class = self.get_serializer_class()

        serializer = serializer_class(objs, many=True)
        # 3. 返回drf的响应
        return Response(serializer.data)


class MixinCreateView:
    def post(self, request, format=None):
        # 1. 创建序列化器对象
        serializer = self.get_serializer(data=request.data)
        # 2. 校验
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

4.通用视图

#drf类视图
class CustomGenericApiView(APIView):
    """
    自定义通用视图
    """
    # 视图使用的查询集
    queryset = None
    # 序列化器类
    serializer_class = None

    def get_queryset(self):
        if self.queryset is None:
            raise ValueError('必须设置一个queryset属性')

        queryset = self.queryset

        queryset = queryset.all()
        return queryset

    def get_serializer_class(self):
        if self.serializer_class is None:
            raise ValueError('必须设置一个serializer_class属性')
        return self.serializer_class

    def get_serializer(self, instance=None, data=empty, **kwargs):
        serializer_class = self.get_serializer_class()
        return serializer_class(instance, data, **kwargs)


class StudentListCreateView(CustomGenericApiView, MixinListView, MixinCreateView):
    """
    学生列表,创建视图
    """
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

##rest_framework提供的通用视图
#(generics.RetrieveAPIView,generics.UpdateAPIView,generics.DestroyAPIView等等)
class StudentDetailUpdateDeleteView(generics.RetrieveAPIView,
                                    generics.UpdateAPIView,
                                    generics.DestroyAPIView,
                                    ):
    """
    学生详情,更新,删除视图
    """
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

路由设置

from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from . import views


# 通过视图集创建视图,并为视图绑定所需要的http方法
student_list_create = views.StudentViewSet.as_view({'get': 'list', 'post': 'create'})
student_detail_update_delete = views.StudentViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})

urlpatterns = [
  # 添加到应用路由中
    path('students/', student_list_create, name='student-list-create'),
    path('students/<int:pk>/', student_detail_update_delete, name='student-detail-update-delete'),  
]

# 处理一下路由,可以选择不同的渲染格式
urlpatterns = format_suffix_patterns(urlpatterns)

5.视图集

drf框架包含了一个处理视图集的抽象,还自动处理url。

视图集类与视图类几乎是相同,不同的是提供retrieve,update这样的操作,而不是put,get.

class CourseViewSet(ModelViewSet):
    """
    课程列表,创建视图
    """
    queryset = Course.objects.all()
    serializer_class = CourseSerializer


class StudentViewSet(ModelViewSet):
    """
    学生视图集
    """
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

路由设置

from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from rest_framework.routers import DefaultRouter
from . import views

# 创建一个路由器帮我们生成视图集上的路由
router = DefaultRouter()
# 注册课时视图集到路由对象
router.register(r'courses', views.CourseViewSet)

urlpatterns = [
   
]

# 处理一下路由,可以选择不同的渲染格式
urlpatterns = format_suffix_patterns(urlpatterns)

urlpatterns.append(path('', include(router.urls)))

Models.py代码

from django.db import models
from django.db.models import UniqueConstraint


class Student(models.Model): # 必须继承
    name = models.CharField('姓名', max_length=20, help_text='姓名')
    age = models.SmallIntegerField('年龄', null=True, blank=True, help_text='年龄')
    sex = models.SmallIntegerField('性别', default=1, help_text='性别')
    qq = models.CharField('qq号码', max_length=20, null=True, blank=True, unique=True, help_text='qq号码')
    phone = models.CharField('手机号码', max_length=20, null=True, blank=True, unique=True, help_text='手机号码')
    channel = models.ForeignKey('Channel', on_delete=models.SET_NULL, null=True, verbose_name='渠道', help_text='渠道来源', related_name='students')

    c_time = models.DateTimeField('创建时间', auto_now_add=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'tb_student'   # 设置创建表示的表名
        verbose_name = '学生信息'
        verbose_name_plural = verbose_name  # django admin中显示模型的说明
        # ordering = ['-age']  # 安装age从大到小排序


class Channel(models.Model):
    name = models.CharField('名称', max_length=20, help_text='名称', unique=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'tb_channel'
        verbose_name = '渠道来源'
        verbose_name_plural = verbose_name


class Course(models.Model):
    name = models.CharField('课程名称', max_length=24, help_text='课程名称', unique=True)
    price = models.IntegerField('价格', help_text='课程价格')
    period = models.SmallIntegerField('课时', help_text='课时,以小时为单位')
    students = models.ManyToManyField(Student, through='Entry', verbose_name='学生', help_text='包名课程的学生')

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'tb_course'
        verbose_name = '课程表'
        verbose_name_plural = verbose_name


class Entry(models.Model):
    student = models.ForeignKey(Student, verbose_name='学生', help_text='报名学生', on_delete=models.PROTECT)
    course = models.ForeignKey(Course, verbose_name='课程', help_text='报名课程', on_delete=models.PROTECT, db_constraint=False)
    c_time = models.DateTimeField('报名时间', auto_now_add=True, help_text='报名时间')

    def __str__(self):
        return '{}-{}'.format(self.student.name, self.course.name)

    class Meta:
        db_table = 'tb_entry'
        verbose_name = '报名表'
        verbose_name_plural = verbose_name
        constraints = [
            UniqueConstraint(fields=['student', 'course'], name='unique_student_course')
        ]


class StudentDetail(models.Model):
    STATION_CHOICES = [
        ('功能测试工程师', '功能测试工程师'),
        ('自动化测试工程师', '自动化测试工程师'),
        ('测试开发工程师', '测试开发工程师'),
        ('测试组长', '测试组长'),
        ('测试经理', '测试经理'),
    ]

    class SalaryChoice(models.TextChoices):
        FIRST = '5000以下', '5000以下'
        SECOND = '5000-10000', '5000-10000'
        THIRD = '10000-15000', '10000-15000'
        FOURTH = '15000-20000', '15000-20000'
        FIFTH = '20000以上', '20000以上'

    student = models.OneToOneField(Student, verbose_name='学生', on_delete=models.CASCADE, help_text='学生', null=True)
    city = models.CharField('所在城市', max_length=24, help_text='所在城市', null=True, blank=True)
    company = models.CharField('任职公司', max_length=48, help_text='任职公司', null=True, blank=True)
    station = models.CharField('岗位', max_length=24, help_text='岗位', choices=STATION_CHOICES, default='功能测试工程师' )
    salary = models.CharField('薪资', max_length=24, help_text='薪资区间', choices=SalaryChoice.choices, default=SalaryChoice.FIRST)

    def __str__(self):
        return self.student.name

    class Meta:
        db_table = 'tb_student_detail'
        verbose_name = '学生详情表'
        verbose_name_plural = verbose_name


class Topping(models.Model):
    name = models.CharField('名称', max_length=24)


class Pizza(models.Model):
    name = models.CharField('名称', max_length=24)
    toppings = models.ManyToManyField(Topping)

Serializers.py代码

from rest_framework import serializers
from rest_framework.validators import UniqueValidator

from .models import Student, Course


class CourseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Course
        exclude = ['students']


class StudentSerializer(serializers.ModelSerializer):
    qq = serializers.CharField(allow_blank=True, allow_null=True, help_text='qq号码', label='Qq号码', max_length=20, required=False,
                   validators=[ UniqueValidator(queryset=Student.objects.all())],
                               error_messages={
                                   'max_length': 'qq号码长度大于20位'
                               })
    phone = serializers.RegexField(r'^1[3-9]\d{9}$',allow_blank=True, allow_null=True, help_text='手机号码', label='手机号码', max_length=11, min_length=11, required
    =False, validators=[ UniqueValidator(queryset=Student.objects.all())])

    # 元信息
    class Meta:
        # 指定根据哪个模型生成序列化器
        model = Student
        # 指定序列化哪些字段
        # fields = ['id', 'name', 'sex']
        # 所有字段
        fields = '__all__'
        # fields = ['id', 'name', 'channel_name']
        # 排除
        # exclude = ['id']


class CustomStudentSerializer(serializers.Serializer):
    """
    学生序列化器
    """
    # 定义需要序列化、反序列化的字段
    id = serializers.IntegerField(label='学生id', read_only=True)
    name = serializers.CharField(label='姓名')
    sex = serializers.IntegerField(label='性别', default=1)
    age = serializers.IntegerField(label='年龄', required=False, allow_null=True)
    qq = serializers.IntegerField(label='qq号码', required=False, allow_null=True)
    phone = serializers.IntegerField(label='手机号码', required=False, allow_null=True)
    channel = serializers.CharField(label='渠道', read_only=True)
    c_time = serializers.DateTimeField(label='创建时间', read_only=True)

    def create(self, validated_data):
        """
        创建对象时调用
        :param validated_data:
        :return:
        """
        return Student.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        更新对象时调用
        :param instance:
        :param validated_data:
        :return:
        """
        for key, value in validated_data.items():
            setattr(instance, key, value)

        instance.save()
        return instance

标签:return,name,models,mixins,视图,图集,data,class,serializer
From: https://www.cnblogs.com/chenxdnote/p/17086350.html

相关文章

  • Qt模型视图结构4_代理
    代理说明代理使用的类为QStyledItemDelegate.自定义代理需要实现以下4个函数:自定义代理四个函数的说明四个函数的原型:virtualQWidget*createEditor(QWidget*parent......
  • Qt模型视图结构3_模型索引与模型的常用函数
    目录前言模型索引相关函数模型索引与模型访问和修改数据项的方法前言在数据项、模型以及视图三者之间,模型索引扮演着至关重要的角色。因此在此将模型索引的函数列举一下......
  • drf之视图
    #1.http请求响应drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作。所以在django原有的django.views.View类基础上,drf封装了多个视图子类出来提供给我们......
  • CAP4——视图引用功能介绍
    功能说明:视图引用是将基础数据汇总到一张表中,并且可来源于不同表单的视图进行聚合显示,实现基础数据的分离存储管理、和聚合拼装显示,同时可以减少自动关联以及触发等业务......
  • 华为交换机系统视图状态system-view超时设置
    配置华为交换机是,频繁退出系统视图状态system-view,可以通过设置超时时长处理设置超时时长为1分30秒system-view[huawei]user-interfaceconsole0[huawei-ui-console......
  • 《中国地质图集》网页版
    公众号【地质掘墓人】曾经发布了《中国地质图集》电子版,其中的图片内容很完整,但网页却无法正常使用,故我基于原文件中的图文,参考其网页设计效果,重新制作了一版网页程序。1......
  • Dynamics 365 视图界面,通过分隔符实现批量查询数据(已知编号数组,直接复制到视图可以直
    效果:  源码实现:publicclasstest_RetrieveMultiple_pre:IPlugin{publicvoidExecute(IServiceProviderserviceProvider){//上下文......
  • 12.1 SQL Server视图
    SQLServer视图(Views)目录SQLServer视图(Views)简介视图的优点安全简单一致性创建视图示例创建一个简单视图重新定义视图使用聚合函数创建视图删除视图简介示例删除一个......
  • 图集Sprite作为材质贴图显示
    效果使用的图集 测试shader注意:如果Sprite带有透明度,注意使用Blend,否则透明部分将显示为黑色Shader"My/SpriteToMatTex"{Properties{_MainT......
  • 数据可视化大屏高德地图javascript webAPI开发的智慧治安物联网管理系统实战解析(web
    文章目录​​高德地图开发系列文章目录​​​​前言​​​​一、项目说明​​​​二、核心代码开发​​​​1.引入库​​​​2.构建DOM容器​​​​3.高德地图开发​​​​(1......