静安区网站建设,免费做产品画册的网站,怎么做网站和艺龙对接,公司注册资金减少意味着什么文章目录 前言一、问题二、解决 前言
最近在复习django的时候#xff0c;发现了一个有趣的问题#xff0c;解决了之后特意记录下来#xff0c;以供以后参考。
一、问题
相信大家使用django的时候#xff0c;被其DRF的强大功能所折服#xff0c;因为它能通过简单的代码就… 文章目录 前言一、问题二、解决 前言
最近在复习django的时候发现了一个有趣的问题解决了之后特意记录下来以供以后参考。
一、问题
相信大家使用django的时候被其DRF的强大功能所折服因为它能通过简单的代码就能帮助我们实现增删改查等最简单的操作。我的demo代码如下 模型类代码models.py
from django.db import modelsclass StudentInfo(models.Model):name models.CharField(max_length10, verbose_name姓名)sex models.CharField(max_length1, verbose_name性别)from_class models.ForeignKey(ClassInfo, on_deletemodels.CASCADE)序列化器代码serializers.py
from rest_framework import serializers
from demo import modelsclass StudentInfoSerializer(serializers.ModelSerializer):class Meta:model models.StudentInfofields __all__
视图代码views.py
from rest_framework.viewsets import ModelViewSet
from .models import StudentInfo
from .serializers import StudentInfoSerializerclass DemoView(ModelViewSet):queryset StudentInfo.objects.all()serializer_class StudentInfoSerializer路由代码urls.py
from rest_framework.routers import SimpleRouter, DefaultRouter
from .views import DemoView
urlpatterns []# demo_route SimpleRouter()
demo_route DefaultRouter()demo_route.register(demo, DemoView, basenamedemo)urlpatterns demo_route.urls最后在项目的主路由里面添加路径即可(需要在settings.py里面注册app)
from django.contrib import admin
from django.urls import path, includeurlpatterns [path(admin/, admin.site.urls),path(user/, include(user.urls)),path(, include(demo.urls))
]效果 但是这样会出现一个问题就是无法控制序列化结果显示的字段。例如在同一个项目中可能会出现多个场景一个场景只需要用户的name和sex字段一个场景只需要用户的name字段一个场景则需要用户的全部字段按照以上方法就需要设置三个序列化器了显然不符合实际应用。那么有没有办法可以兼顾便捷和灵活呢
二、解决
解决方法很简单重写序列化器的__init__()方法即可 serializers.py
# 动态修改fileds字段
class StudentInfoSerializer(serializers.ModelSerializer):此处的fields字段是用来替换上面Serializer内部Meta类中指定的fields属性值def __init__(self, *args, **kwargs):# 在super执行之前# 将传递的fields中的字段从kwargs取出并剔除避免其传递给基类ModelSerializer# 注意此处fields中在默认self.fields属性中不存在的字段将无法被序列化 也就是fields中的字段应该是self.fields的子集fields kwargs.pop(fields, None)super(StudentInfoSerializer, self).__init__(*args, **kwargs)if fields is not None:# 从默认self.fields属性中剔除非fields中指定的字段(两个集合相减会提出多余的元素)allowed set(fields)existing set(self.fields.keys())for field_name in existing - allowed:self.fields.pop(field_name)class Meta:model models.StudentInfofields __all__以上代码的原理也很简单首先获取传入的fields参数(即你想要的字段)然后使用序列化器原有的字段减去你想要的字段就获取了多余的字段最后循环遍历多余的字段将它们从原有的字段中一个一个剔除。 为了更好的展示结果我这里自定义了三个路径 views.py
from django.shortcuts import render# Create your views here.
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from .models import StudentInfo
from .serializers import StudentInfoSerializerclass DemoView(ModelViewSet):queryset StudentInfo.objects.all()serializer_class StudentInfoSerializeraction(url_pathall_fields, methods[GET], detailFalse)def all_fields(self, request):user_data StudentInfo.objects.all()serializer StudentInfoSerializer(instanceuser_data, manyTrue)return Response(serializer.data)action(url_pathname_sex, methods[GET], detailFalse)def name_sex(self, request):user_data StudentInfo.objects.all()serializer StudentInfoSerializer(instanceuser_data, fields(name, sex), manyTrue)return Response(serializer.data)action(url_pathname_fromclass, methods[GET], detailFalse)def name_fromclass(self, request):user_data StudentInfo.objects.all()serializer StudentInfoSerializer(instanceuser_data, fields(name, from_class), manyTrue)return Response(serializer.data)效果如下 可以看出根据传入的fields的不同返回不同的结果。