其他分享
首页 > 其他分享> > 多表序列化 请求与响应

多表序列化 请求与响应

作者:互联网

概要

1.多表序列化

# 图书表,出版社表,作者,作者详情   (中间表)

1.1路由层

urlpatterns = [
    path('admin/',admin.site.urls),
    path('books/',views.BookView.as_view()),       path('books/<int:pk>',views.BookDetailView.as_view()),
]

1.2 视图类

from .models import Book,Author,AuthorDetail,Publish
from rest_framework.response import Response
from .serializer import BookSerializer
class BookView(APIView):
    def get(self,request):
        book_list=Book.objects.all()
        
# 序列化 read
    ser=BookSerializer(book_list,many=True)
    return Response(ser.data)

# 反序列化的新增
def post(self,request):
    ser=BookSerializer(data=request.data)
    if ser.is_valid():
         ser.save()
         return Response({'code':100,'msg':'新增成功'})
    else:
        return Response({'code':101,'msg':'新增失败','err':ser.errors})
    
class BookDetailView(APIView):
    def get(self, request,pk):
        book=Book.objects.all().filter(pk=pk).first()
        ser=BookSerializer(book)
    
    def put(self,request,pk):
        book = Book.objects.all().filter(pk=pk).first()
        ser = BookSerializer(instance=book,data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code':100,'msg':'修改成功'})
        else:
            return Response({'code':101,'msg':'修改失败','err':ser.errors})        

1.3 序列化类

from rest_framework import serializers
知识点:绝对导入与相对导入的区别
# 相对导入----一个py文件中如果使用相对导入,这个文件不能以脚本运行(大白话:就是在pycharm中不能通过右键直接运行代码)
from .models import Book

# 绝对导入
from app01.models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
         model=Book
         fields=['nid','name','price','publish_detail', 'author_list','publish','authors']
        extra_kwargs={
            'publish':{'write_only':True},
            'authors': {'write_only': True},
        }

# 方式一:重写字段+必须配合一个方法,方法返回啥 该字段就是什么 ===该字段只能序列化

publish_detail=serializers.SerializerMethodField(read_only=True)
	def get_publish_detail(self,obj):
        # 就是当前book对象
        print(obj)
        return {'name':obj.publish.name,'city':obj.publish.city}
    
# 方式二:在表模型models中写方法,在序列化类中写到fields中


需求:把所有的作者:作者名字和作者addr
    
# 方式一
 author_list=serializers.SerializerMethodField(read_only=True)
     def get_author_list(self,obj):
     # 作者有多个,先拿到所有作者,---》正向查询
    	author_list=[]
        for author in obj.authors.all():   
         author_list.append({'name':author.name,'addr':author.author_detail.addr})
            return author_list 

1.4模型层

from django.db import models

# Create your models here.
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    
   # publish_date = models.DateField(null=True)

#关联关系
publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)

authors=models.ManyToManyField(to='Author') 

#自动生成中间表
def __str__(self):
    return self.name

# def publish_detail(self):
#     return {'name':self.publish.name,'email':self.publish.email}

# 作者详情
# def author_list(self):
#     author_list=[]
#     for author in self.authors.all():
#         author_list.append({'name':author.name,'addr':author.author_detail.addr})
#     return author_list

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)
    
"""
on_delete可以选择的请情况
        -models.CASCADE   级联删除
        -models.SET_NULL  关联字段置为空    null=True
        -models.SET_DEFAULT 关联字段设为默认值 default=0
        -models.DO_NOTHING     由于数据库有约束会报错,去掉外键关系(公司都不建立外键)
        -on_delete=models.SET(值,函数内存地址)  设置上某个值,或者运行某个函数
"""

class AuthorDetail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)
    
class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()
    def __str__(self):
        return self.name

2 请求与相应

2.1请求

# django ---->请求对象---->request
# django ---->响应对象---->render、HttpResponse、Redirect、JsonResponse---->最终本质都是HttpResponse

# 在drf中--->请求对象---->新的request--->drf的Request类的对象

# drf的请求对象
	-request.data
    -request.query_params
    -request.FILES

# 控制前端传入的编码格式--->默认 :urlencoded,form-data,json

# 全局生效
项目配置文件中加入
REST_FRAMEWORK = {
            'DEFAULT_PARSER_CLASSES':[
                'rest_framework.parsers.JSONParser',  # 能够解析json
 'rest_framework.parsers.FormParser',  # 能够解析urlencoded
 'rest_framework.parsers.MultiPartParser', #能够解析form-data
               ],
        }

# 局部生效---》视图类中配置
class BookView(APIView):
    	parser_classes = [JSONParser,]
        
# 优先级:先找 视图类---》项目配置文件----》drf配置文件

2.2 响应

from rest_framework.response import Response

#初始化对象,传入的参数,response对象的属性 五个
data=None,   # 要序列化的数据,字典,列表,字符串status=None, # http响应状态码
headers=None, # 响应头---》字典

前三个是最重要的 剩下两个基本不会用
template_name=None, #模板名字---》浏览器看的时候,看到好看的页面,postman看,纯json
content_type=None # 默认json格式,前后端分离项目,前端传用json,后端响应也用json格式


# 浏览器看的时候,看到好看的页面,postman看,纯json----》想控制,都是json格式,无论是浏览器还是postman

# 全局生效
项目配置文件中加入
REST_FRAMEWORK = {
            'DEFAULT_RENDERER_CLASSES':[
          		'rest_framework.renderers.JSONRenderer', #json格式

'rest_framework.renderers.BrowsableAPIRenderer', #浏览器格式
            ],
}
# 局部生效---》视图类中配置
  class BookView(APIView):
    	renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
        
 # 优先级:先找 视图类---》项目配置文件----》drf配置文件

标签:多表,name,author,models,self,list,publish,响应,序列化
来源: https://www.cnblogs.com/wht488232/p/16382992.html