04视图类

【一】改项目名

1.选择directory后,会发现,项目后面有个[],意思为他的配置还是02的,有两个解决办法

a.改完文件夹名去选择project项目名会直接给你改项目配置,就不会有中括号

b.在删前要把项目关了,在文件夹里删了他的idea(也就是他的配置文件)然后在文件夹,file--》open就会重新配置,就没有中括号了

但还是发现项目名和配置名还是不一致,且项目能运行,但是我们要保证一致,所以去把这个项目重命名drf002,就不能运行了

解决办法:

0.现在整个项目全局替换drf02,替换成drf002

1.设置里搜索django,如一下配置

2.移除运行里django重新生成一个

但是改了那个项目的就完了

【二】 模块与包及导入规则

1.模块--》就是py文件,在别的py文件把他导入,这个py文件就叫模块
​
2.脚本--》一个py文件,能直接右键运行
​
3.包--》文件夹下有__init__.py文件,并且包下可以有很多py文件--》py文件中有很多方法和类
​
# 重点:导入模块或包的规则
    -1 绝对导入--》根指的是 环境变量,如果该路径在环境变量中就可以作为根,导入
        -打印环境变量:sys.path
        eg: 新建一个lib文件夹,里有个是模块,si模块里有demo方法
        form lib.s1 import demo
    -2 相对导入
        -相当于当前的py文件
        eg:在你同级的情况下建一个s1模块,里面写demo方法
        from .s1 import demo
            print(demo())
​
        ['D:\\pycharm\\pxrj\\drf\\drf02',# 项目目录
         'D:\\pycharm\\pxrj\\drf\\drf02', 
         'D:\\python3.10\\python310.zip', 因为有这个所以能直接 import os,time
         'D:\\python3.10\\DLLs', 
         'D:\\python3.10\\lib', 
         'D:\\python3.10', 
         'D:\\python3.10\\lib\\site-packages',装第三模块的地方,我梦去看django都在里面所以我们可以直接import django]
​
        
"""
 # 以后如果我们写包,写第三方包
    -可以直接  from 包名  import 即可   
        # 因为如果给别人用,别人下载完会在 site-packages  在环境变量
        # 如果自己用,我们会放在项目根路径, 项目根路径  在环境变量中eg: 新建一个lib文件夹,里有个是模块,si模块里有demo方法
        form lib.s1 import demo
"""

【三】断言assert(断定)

####1 断言的使用#####
assert 断不报错的条件(没有达到某条件是真就抛出) ,"报错的字符串"--->抛出AssertionError
​
如果不用断言,可以用主动报错raise
name="llh"
if name =="llh":
    raise Exception("名字不能为llh")
else:
    print("对")
    
    
####2 使用断言的位置 #####
    -断定 某些值一定存在
    -断定 某个值必须为 字符串类型  等等等    

【四】drf之请求响应

4.1请求-支持的编码格式

1.drf编码,可以支持三种编码格式form-data,urlencoded,json
    从request.data中取出请求体的数据
​
2.后期,有个上传文件接口--》只能接收form-data类型,其他类型不允许,怎么做
    -控制某个接口,只能处理,一种编码格式,其他都不行
​
"""没有用我们指定的会报这个错
{
    "detail": "不支持请求中的媒体类型 “application/json”。"
}
"""    
    
3.使用方式1(局部使用)--》在视图类上直接配置,如果不配就会默认三种,如果空列表,就全都禁用
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
class Book_View(APIView):
    parser_classes = [MultiPartParser]
​
4.使用方式2(全局使用)--》在setting中,所有视图类都会使用这个解析
由以下的提示可知,我们写配置像下面示例一样去写就行在哪看的
from rest_framework import settings点进这个settings里就可以看
就只写下面这个就行
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser',
    ],
}
​
5.全局使用了,局部再定制,使用的是局部的,因为优先级局部高
class BookView(APIView):
    parser_classes = [JSONParser]
    
6.优先级使用
    -视图定制的
    -配置中的
    -最后才会使用drf内置的,三种都有
 

4.2响应

1.postman 返回json--》浏览器会返回好看的页面
2.控制,要求postman只返回json格式,浏览器也是只返回json格式
如何做:
3.局部使用
from rest_framework.renderers import BrowsableAPIRenderer,JSONRenderer
class BookView(APIView):
    renderer_classes = [JSONRenderer]
    
4.全局
REST_FRAMEWORK = {
      'DEFAULT_RENDERER_CLASSES': [
        # 'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}
5.全局使用了,局部再定制,使用的是局部的,因为优先级局部高
class BookView(APIView):
    renderer_classes = [JSONRenderer]
    
"""优先级和上面一样"""

【五】两个视图基类(APIView,GenericAPIView)

5.1基于APIView+序列化类+Response写5个接口

1.view.py
from rest_framework.response import Response
from rest_framework.views import APIView
​
from .models import Book3, AuthorDetail, Author
from .serializer import BookModelSerialzier, AuthorSerializer
​
​
class Book_View(APIView):
    def get(self, request):
        obj = Book3.objects.all()
        if obj:
            serializer = BookModelSerialzier(instance=obj, many=True)
            return Response(serializer.data)
        return Response({"code": 201, "msg": "查询失败"})
​
    def post(self, request):
        print(request)
        print(type(request.data))
        serializer = BookModelSerialzier(data=request.data)
        if serializer.is_valid():
            # 处理有效的数据(例如保存到数据库)
            serializer.save()
            # 返回序列化后的数据或响应
            return Response(serializer.data)
        else:
            # 返回错误信息
            return Response(serializer.errors, status=400)
​
class BookDetailView(APIView):
    def put(self,request,book_id):
        obj=Book3.objects.filter(pk=book_id).first()
        if obj:
            serializer=BookModelSerialzier(data=request.data,instance=obj)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
        return Response({"code": 201, "msg": "修改失败"})
​
    def get(self,request,book_id):
        obj = Book3.objects.filter(pk=book_id).first()
        if obj:
            serializer = BookModelSerialzier(instance=obj)
            return Response(serializer.data)
        return Response({"code": 201, "msg": "查询失败"})
    def delete(self,request,book_id):
        res=Book3.objects.filter(pk=book_id).delete()
        if res:
            return Response({"code": 200, "msg": "删除成功"})
        else:
            return Response({"code": 201, "msg": "删除失败"})
class AuthorView(APIView):
    def get(self,request):
        obj=Author.objects.all()
        if obj:
            serializer=AuthorSerializer(instance=obj,many=True)
            return Response(serializer.data)
        else:
            return Response({"code":1001,"msg":"查询失败"})
    def post(self,request):
        serializer=AuthorSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)
class AuthorDetailView(APIView):
    def put(self,request,author_id):
        obj=Author.objects.filter(pk=author_id).first()
        if obj:
            serializer = AuthorSerializer(instance=obj, data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
        return Response({"code": 201, "msg": "修改失败"})
​
    def get(self,request,author_id):
        obj = Author.objects.filter(pk=author_id).first()
        if obj:
            serializer = AuthorSerializer(instance=obj)
            return Response(serializer.data)
        return Response({"code": 201, "msg": "查询失败"})
    def delete(self,request,author_id):
        res=Author.objects.filter(pk=author_id).delete()
        if res:
            return Response(status=200)
        else:
            return Response({"code": 201, "msg": "删除失败"})
2.serializer.py
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from .models import Book3, Publish, Author, AuthorDetail
class BookModelSerialzier(serializers.ModelSerializer):
    class Meta:
        model = Book3
        fields = ['id','name', 'price', 'publish', 'authors', 'publish_detail', 'author_list']  # 新增的publish_real 也要注册
        extra_kwargs = {'name': {'max_length': 8}, 'price': {'max_value': 100},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},
                        }
​
        def validate_name(self, name):
            if "sb" in name:
                raise ValidationError("名字中不能带有sb")
​
    publish_detail = serializers.DictField(read_only=True)
    author_list = serializers.ListField(read_only=True)
class AuthorDetailSerializar(serializers.Serializer):
    gender = serializers.IntegerField()
    phone = serializers.IntegerField()
class AuthorSerializer(serializers.Serializer):
    name = serializers.CharField()
    age = serializers.IntegerField()
    addr = serializers.CharField()
    gender = serializers.CharField(write_only=True)
    phone = serializers.IntegerField(write_only=True)
    author_detail=AuthorDetailSerializar(read_only=True)
    def create(self, validated_data):
        gender=validated_data.pop('gender')
        phone=validated_data.pop('phone')
        new_dict={"gender":gender,"phone":phone}
        authordetail=AuthorDetail.objects.create(**new_dict)
        validated_data["author_detail_id"]=authordetail.id
        print(validated_data)
        author = Author.objects.create(**validated_data)
        return author
    def update(self,instance, validated_data):
        print(validated_data)
        gender=validated_data.pop('gender')
        phone=validated_data.pop('phone')
        instance.author_detail.gender=gender
        instance.author_detail.phone=phone
        print(validated_data)
        for key in validated_data:
            # key是一个字符串,字符串和对象就可以想到反射
            setattr(instance, key, validated_data[key])
        return instance
3.models.py
from django.db import models
class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
class Book3(models.Model):
    name = models.CharField(max_length=32)
    price = models.IntegerField()
    publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True)
    authors=models.ManyToManyField(to='Author')
    def publish_detail(self):
        return {"name":self.publish.name,"addr":self.publish.addr}
    def author_list(self):
        l=[]
        obj=self.authors.all()
        for i in obj:
            l.append({'name':i.name,'age':i.age})
        return l
class AuthorDetail(models.Model):
    gender=models.IntegerField(choices=((1,'男'),(2,'女'),(0,'未知')))
    phone=models.IntegerField()
​
class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    addr = models.CharField(max_length=32)
    author_detail = models.OneToOneField(to=AuthorDetail, on_delete=models.SET_NULL, null=True)

5.1基于GenericAPIView+序列化类+Response写5个接口

1.与APIView不一样的地方
就是多写了两个类属性,以及多了三个get方法
#类属性
queryset = Book.objects.all()
serializer_class = BookModelSerialzier
#在方法内把数据扔进序列化类里  
 serializer = self.get_serializer(instance=obj, many=True)
 
 #获取多条数据
 obj=self.get_queryset()
 #获取单条
 obj=self.get_object()
#不同的只有视图类,**序列化类和路由跟之前一样**
class Book_View(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzier
    def get(self, request):
        obj=self.get_queryset()
        if obj:
            serializer = self.get_serializer(instance=obj, many=True)
            return Response(serializer.data)
        return Response({"code": 201, "msg": "查询失败"})

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            # 处理有效的数据(例如保存到数据库)
            serializer.save()
            # 返回序列化后的数据或响应
            return Response(serializer.data)
        else:
            # 返回错误信息
            return Response(serializer.errors, status=400)

class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzier
    def put(self,request,book_id):
        obj=self.get_object()
        if obj:
            serializer=self.get_serializer(data=request.data,instance=obj)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
        return Response({"code": 201, "msg": "修改失败"})

    def get(self,request,book_id):
        obj=self.get_object()
        if obj:
            serializer = self.get_serializer(instance=obj)
            return Response(serializer.data)
        return Response({"code": 201, "msg": "查询失败"})
    def delete(self,request,book_id):
        res=self.get_object().delete()
        if res:
            return Response({"code": 200, "msg": "删除成功"})
        else:
            return Response({"code": 201, "msg": "删除失败"})

【六】5个视图扩展类

# 1 5个视图扩展类---》必须配合GenericAPIView
"""从上面的继承GenericAPIView的类发现,很多代码都是一样的能不能做个封装"""
举个下述类中的源码例子,不难发现是我们之前的步骤做了封装
"""    
	def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
        #create方法负责处理请求数据的验证、序列化、以及创建响应。而perform_create则专注于执行与数据库相关的操作,如保存对象。这种分离使得代码更加清晰和模块化,也更容易维护和扩展。
       def perform_create(self, serializer):
        serializer.save()
        """
from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin, CreateModelMixin, 
									
DestroyModelMixin, ListModelMixin


#2 使用只要继承GenericAPIView,RetrieveModelMixin你想要哪个接口,编写一下 get 、post、delete、get、put--》就能实现某个或某几个接口
"""注意在定义路由的时候,那个路径转换器的名称必须是pk否则会报错"""

"""下面的super可以用self替换,但是self从自身开始找,super从最近父类开始找,都能找到,但是super更快效率更高
"""
**路由和序列化类是一样的**就视图类不同
class Book_View(GenericAPIView,ListModelMixin,CreateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzier
    def get(self, request):
        return super().list(request)

    def post(self, request):
        return super().create(request)

class BookDetailView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzier
    def put(self,request,pk):
        return super().update(request,pk)

    def get(self,request,pk):
        return super().retrieve(request,pk)
    def delete(self,request,pk):
        return super().destroy(request,pk)

【七】9 个视图子类

#1 就是上面五个视图扩展类的进行组合多出四个就总共九个了
from rest_framework.generics import ListAPIView, CreateAPIView, UpdateAPIView, RetrieveAPIView, DestroyAPIView
from rest_framework.generics import ListCreateAPIView
from rest_framework.generics import RetrieveUpdateDestroyAPIView, RetrieveUpdateAPIView, RetrieveDestroyAPIView
#2.使用方法和上面一致,
class Book_View(GenericAPIView,ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzier
    def get(self, request):
        return super().list(request)

    def post(self, request):
        return super().create(request)

class BookDetailView(GenericAPIView,RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzier
    def put(self,request,pk):
        return super().update(request,pk)

    def get(self,request,pk):
        return super().retrieve(request,pk)
    def delete(self,request,pk):
        return super().destroy(request,pk)

【八】视图集

#1.**序列化类是一样的**
**路由和视图都不一样**
"""若视图写完,没弄路由的映射,会报错,根据报错进行解析映射
TypeError: The `actions` argument must be provided when calling `.as_view()` on a ViewSet. For example `.as_view({'get': 'list'})`"""
​
#     # 这个类里就没有  get  get       post     put     delete  方法了
#     # 这个类里有:    list retrieve  create  update   destroy 方法
​

路由

from app01.views import Book_View,BookDetailView
​
urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', Book_View.as_view({'get': 'list','post':'create'})),
    path('books/<int:pk>', BookDetailView.as_view({'get': 'retrieve','put':'update','delete':'destroy'})),
]

视图

from rest_framework.viewsets import ModelViewSet
class Book_View(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzier

class BookDetailView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerialzier

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值