drf 04——多表序列化、请求与响应

多表序列化

路由

urlpatterns = [
    path('books/', views.Books.as_view()),
    path('books/<int:pk>/', views.BooksDetail.as_view()),
]

视图类

class Books(APIView):
    def get(self, request):
        books = Book.objects.all()
        ser = BookSerializer(instance=books, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        else:
            return Response({'code': 101, 'msg': '保存失败', 'error': ser.errors})
class BooksDetail(APIView):
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book)
        return Response(ser.data)

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).first().delete()
        return Response({'code': 100, 'msg': '删除成功'})

    def put(self, request, pk):
        book = Book.objects.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': '保存失败', 'error': ser.errors})

序列化类

# 方式一:重写字段+必须配一个方法 方法返回啥 该字段就是啥————>该字段只能序列化
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish', 'authors', 'publish_detail', 'author_list']
        extra_kwargs = {
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},                        
                    }

    publish_detail = serializers.SerializerMethodField(read_only=True)  
    def get_publish_detail(self, obj):
        # obj即为当前的Book对象
        return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}

    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, 'age': author.age,
                                'addr': author.author_detail.addr})
        return author_list
# 方式二: 在models中写方法 在序列化类中写到fields中
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish', 'publish_detail', 'authors', 'author_list']
        extra_kwargs = {
            'publish': {'write_only': True},
            'authors': {'write_only': True}
        }
        # 可重写字段 也可写在extra_kwargs内  仅用于前端展示
        publish_detail = serializers.SerializerMethodField(read_only=True)
        author_list = serializers.SerializerMethodField(read_only=True)    


        
'models.py'        
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 = 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        

请求与响应

请求

# django
	请求对象---->request
	响应对象---->render,HttpResponse,rediect,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配置文件

响应

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格式

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

补充

相对导入和绝对导入

# 绝对导入
	绝对指的是环境变量	sys.path里的路径	
    	  项目根路径在pycharm自动加入到环境变量

# 相对导入
	一个py文件中如果使用相对导入,这个文件不能以脚本运行

django国际化配置

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

models的级联删除相关

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(值,函数内存地址)  设置上某个值,或者运行某个函数
    '''

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

def test(request):
    obj = HttpResponse('ok')
    # obj = render()
    # obj = redirect()
    # obj = JsonResponse()
    obj['xxx'] = 'ooo'	
    return obj
posted @ 2022-06-16 21:00  扶我上码  阅读(92)  评论(0)    收藏  举报