多表序列化与请求和响应


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()
       #序列化
       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)
       return Response(ser.data)

   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文件中如果使用相对导入,这个文件不能以脚本运行
from .models import Book
# # 绝对导入
# from app01.models import Book


class BookSerializer(serializers.ModelSerializer):
   class Meta:
       model=Book
       # fields="__all__"
       fields=['nid','name','price',    'publish_detail', 'author_list',    'publish','authors']
       # depth   不要用 --->外键关联一层,我建议不要超过3 不可控,比如我们只想要某几个字段
       # depth=1
       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 obj.publish.name
       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配置文件

 

 

补充

1 相对导入和绝对导入

# 绝对导入---》绝对指的是 环境变量   sys.path 里面的路径,项目跟路径在pycharm自动加入环境变量
# 相对导入---->一个py文件中如果使用相对导入,这个文件不能以脚本运行

 

2 django国际化配置

# django 国际化---》配置文件改

# 国际化相关
LANGUAGE_CODE = 'zh-hans'
#时区:改成东八区
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False

3 models 的级联删除相关

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

4 原生django,如何向响应头写数据

def test(request):
   obj=HttpResponse('ok')
   # obj=render()
   # obj=redirect('/index')
   # obj=JsonResponse()
   obj['xxx']='ooo'  #直接放
   return obj


原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/270337.html

(0)
上一篇 2022年6月25日
下一篇 2022年6月25日

相关推荐

发表回复

登录后才能评论