接口设计

hello world

配置setting.py

#启用DRF模块
INSTALLED_APPS = [
    'rest_framework',
]
#连接远程数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'zufang',
        'HOST': '121.43.123.91',
        'PORT': 3306,
        'USER': 'huadao',
        'PASSWORD': '123456',
        'CHARSET': 'utf8',
        'TIME_ZONE': 'Asia/Shanghai',
    },
}
接口设计

1、注册app,python manage startapp appname

JsonResponse只能处理字典数据,如果给的是个列表,要把safe属性改为False
CONTENT-TYPE告诉浏览器服务器给的是什么类型的数据
面向对象里面的里氏替换原则:任何时候可以使用子类型对象替换父类型

2、第一个接口

views文件编写:
@api_view(('GET', ))	#访问方式
def get_provinces(request: HttpRequest) -> HttpResponse:
    queryset = District.objects.filter(parent__isnull=True)\
        .only('name')	
#select投影
#only  只查某个字段
#defer 不查哪些属性
    serializer = DistrictSimpleSerializer(queryset, many=True)	#序列化
    return Response({
        'code': 10000,
        'message': '获取省级行政区域成功',
        'results': serializer.data
})
项目文件urls.py注册路由:
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')),
]
应用文件url.py注册路由:
urlpatterns = [
    path('districts/', get_provinces),
]
序列化serializers.py
class DistrictSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = District
        fields = ('distid', 'name')
省都市三级联动-FBV

编写接口-FBV

views.py

@api_view(('GET', ))
def get_cities(request: HttpRequest, distid) -> HttpResponse:
    district = District.objects.filter(distid=distid)\
        .defer('parent').first()	#拿到指定对象的详细信息,除了父级parent属性
    serializer = DistrictDetailSerializer(district)
    return Response(serializer.data)

serializers.py

#获取省的详细信息,及所属省下的市级详细信息
class DistrictDetailSerializer(serializers.ModelSerializer):
  	#在序列化器,额外加一个字段,这个字段要通过一个自定义方法来拿到它
    cities = serializers.SerializerMethodField()	
    
    @staticmethod
    def get_cities(district):	#这个方法必须叫这个名字
        queryset = District.objects.filter(parent=district).only('name')
        return DistrictSimpleSerializer(queryset, many=True).data

    class Meta:
        model = District
        exclude = ('parent', )

urls.py

urlpatterns = [
    path('districts/', get_provinces),
    path('districts/<int:distid>/', get_cities),	#获取单个对象id
]
CBV
ListAPIview				获取对象列表
RetrieveAPIView			获取单个对象
RetrieveUpdateAPIView	获取和更新单个对象
CreateAPIView			创建新对象
ListCreateAPIView		创建新对象和查看列表
获取经理人列表-CBV-ListAPIview

APIView --> GenericAPIView --> ListAPIView

views.py

class AgentView(ListAPIView):	#ListAPIView返回的是一个列表
    queryset = Agent.objects.all().only('name', 'tel', 'servstar')
    serializer_class = AgentSimpleSerializer
	# 修改ListAPIView的响应,定制响应格式为json
    # def get(self, request, *args, **kwargs):
    #     resp = super().get(self, request, *args, *kwargs)
    #     return Response({
    #         'code': 10000,
    #         'message': '获取经理人列表',
    #         'results': resp.data
    #     })

serializers.py

class AgentSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Agent
        fields = ('agentid', 'name', 'tel', 'servstar')

urls.py

urlpatterns = [
    path('agents/', AgentView.as_view())
]
获取单个经理人-CBV-RetrieveAPIView

views.py

class AgentView(RetrieveAPIView):	#返回单个对象
    queryset = Agent.objects.all().only('name', 'tel', 'servstar')
    serializer_class = AgentSimpleSerializer

urls.py

urlpatterns = [
    path('agents/<int:pk>', AgentView.as_view())
]
创建并获取经理人列表、获取单个和修改经理人-CBV

views.py

class AgentView(ListCreateAPIView, RetrieveUpdateAPIView):
    queryset = Agent.objects.all().only('name', 'tel', 'servstar')
        def get_serializer_class(self):
        	return AgentCreateSerializer if self.request.method == 'POST' else AgentSimpleSerializer	# 创建更新经理人时要设置详细的信息

	def get(self, request, *args, **kwargs):
        cls = RetrieveUpdateAPIView if 'pk' in kwargs else ListCreateAPIView
        return cls.get(self, request, *args, **kwargs)

urls.py

urlpatterns = [
    path('agents/', AgentView.as_view())
    path('agents/<int:pk>', AgentView.as_view())
]

serializers.py

class AgentSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Agent
        fields = ('agentid', 'name', 'tel', 'servstar')


class AgentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Agent
        exclude = ('estates', )
最终章:只可意会忘记言传

views.py

class AgentView(ListCreateAPIView, RetrieveUpdateAPIView):
    def get_queryset(self):
        queryset = Agent.objects.all()
        if 'pk' not in self.kwargs:
            queryset = Agent.objects.all().only('name', 'tel', 'servstar')
        return queryset

    def get_serializer_class(self):
        return AgentCreateSerializer if self.request.method == 'POST' \
            else AgentSimpleSerializer if 'pk' not in self.kwargs else AgentDetailSerializer

    def get(self, request, *args, **kwargs):
        cls = RetrieveUpdateAPIView if 'pk' in kwargs else ListCreateAPIView
        return cls.get(self, request, *args, **kwargs)

    # def get(self, request, *args, **kwargs):
    #     resp = super().get(self, request, *args, *kwargs)
    #     return Response({
    #         'code': 10000,
    #         'message': '获取经理人列表',
    #         'results': resp.data
    #     })

serializers.py

class AgentSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Agent
        fields = ('agentid', 'name', 'tel', 'servstar')


class AgentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Agent
        exclude = ('estates',)


class AgentDetailSerializer(serializers.ModelSerializer):
    estates = serializers.SerializerMethodField()

    def get_estates(self, agent):
        queryset = agent.estates.all().only('name')
        return EstateSimpleListAPIView(queryset, many=True).data

    class Meta:
        model = Agent
        fields = '__all__'


class EstateSimpleListAPIView(serializers.ModelSerializer):
    class Meta:
        model = Estate
        fields = ('estateid', 'name')

urls.py

urlpatterns = [
    path('agents/', AgentView.as_view()),
    path('agents/<int:pk>', AgentView.as_view()),
]
接口设计第三种方式-CBV-ModelViewSet

views.py

class HouseTypeViewSet(ModelViewSet):
    queryset = HouseType.objects.all()
    serializer_class = HouseTypeSerializer

serializers.py

class HouseTypeSerializer(serializers.ModelSerializer):
    """户型序列化器"""

    class Meta:
        model = HouseType
        fields = '__all__'

urls.py

router = SimpleRouter()
router.register('housetype', HouseTypeViewSet)
urlpatterns += router.urls
Django-ORM问题
Django的ORM框架在遇到关联查询时可能产生的1+n查询问题,严重影响性能
对于多对一和一对一:select_related(关联对象)	
ed:Emp.objects.filter(dept_no=20).select_related('dept')	拿到关联对象
对于多对多: prefetch_related(关联对象)	
Agent.objects.all().prefetch_related('estate')	预抓取关联对象

在Django下如何使用原生sql查询
1.Agent.objects.raw('sql语句')
2.django.db.connections['default'] --> cursor() --> execute('sql语句')
  --> fetchall() / fetchone() / fetchmany(n)
~ ORM框架
    解决Python程序对象模型和关系型数据库关系模型不匹配问题,实现对象模型和关系模型的双向转换
    District.objects.filter(parent__isnull=True).only('name')
    only和defer方法可以指定需要查询的属性或者排除不需要查询的属性,对select语句做投影处理
    Django的ORM框架在遇到关联查询时可能产生1+N查询问题,严重影响性能
    对于多对一和一对一关系:select_related(关联对象)
    Emp.objects.filter(dept__no=20).select_related('dept')
    对于多对多关系:prefetch_related(关联对象)
    Agent.objects.all().prefetch_related('estates')
    可以使用Prefetch对象来定制多对多关系的预抓取方案
    Prefetch('estates', queryset=Estates.objects.all().only('name').order_by('-hot'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值