Django DRF routers路由使用
程序员文章站
2022-07-12 11:11:54
...
代码下载:利用django自带的routers实现对url路由的分发(代码实战)
我们常用的定义url的路由有以下两种方式:
第一种:
urlpatterns = [
url('^student/$',StudentViewSetAction.as_view({'get':'list','post':'create'}))
]
第二种:
# coding:utf-8
from rest_framework import routers
from api.views import *
router = routers.DefaultRouter()
router.register(r'student', StudentViewSetAction, base_name='student')
urlpatterns = []
urlpatterns += router.urls
下面主要讲解第二种方式,第一种比较常见且简单。
1、配置app下面的settings、urls和models。
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
),
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 3,
}
# coding:utf-8
from rest_framework import routers
from api.views import *
router = routers.DefaultRouter()
router.register(r'student', StudentViewSetAction, base_name='student')
urlpatterns = []
urlpatterns += router.urls
# coding:utf-8
from django.db import models
class Teacher(models.Model):
"""老师表"""
name = models.CharField(verbose_name="老师姓名", max_length=16)
motto = models.CharField(verbose_name="格言", max_length=32)
class Student(models.Model):
"""学生表"""
tea = models.ForeignKey(Teacher, on_delete=models.DO_NOTHING, verbose_name="老师")
name = models.CharField(verbose_name="学生姓名", max_length=16)
add_time = models.DateField(verbose_name='添加日期', auto_now_add=True)
age = models.IntegerField(verbose_name='年龄')
2、配置视图。
# coding:utf-8
from django.db import transaction
from django_filters import rest_framework
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from api import models
from api.utils.filter import getUserListFilter
from api.utils.ser import getUserListSerializer
from rest_framework import filters
from rest_framework.decorators import action
class StudentViewSetAction(ModelViewSet):
'''学生视图'''
queryset = models.Student.objects.all()
serializer_class = getUserListSerializer # 数据序列化
filter_backends = (
rest_framework.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter,) # 需要用django查询的固定写法
filter_class = getUserListFilter # 定义过滤查询
ordering_fields = ('tea', 'id') # 排序的字段
def list(self, request, *args, **kwargs):
'''获取学生列表分页'''
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
def create(self, request, *args, **kwargs):
'''新增学生信息'''
return Response({'method': '新增学生信息'})
def update(self, request, pk, *args, **kwargs):
'''修改学生信息'''
return Response({'method': '修改学生信息'})
'''
detail: 声明该action的路径是否与单一资源对应,及是否是xxx/<pk>/action方法名/
True 表示路径格式是xxx/<pk>/action方法名/
False 表示路径格式是xxx/action方法名/
'''
@action(methods=['get'], detail=False)
def read(self, request, *args, **kwargs):
"""
自定义获取
"""
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
@action(methods=['post'], detail=False)
def add(self, request, *args, **kwargs):
"""
自定义新增
"""
return Response({'method': '这个方法也是新增'})
@action(methods=['put'], detail=True)
def edit(self, request, pk, **kwargs):
"""
自定义修改
"""
return Response({'method': '这个方法也是修改'})
3、配置filter过滤类和ser序列化类。
filter:
# coding:utf-8
import django_filters
from django_filters import rest_framework as filters
from api import models
class ProductSourceNameListFilter(django_filters.CharFilter):
def filter(self, qs, value):
value = list(filter(None, value.split(",")))
return super(ProductSourceNameListFilter, self).filter(qs=qs, value=value)
class getUserListFilter(django_filters.rest_framework.FilterSet):
# method one
# tea = ProductSourceNameListFilter(field_name='tea', lookup_expr='in')
# method two
tea = filters.CharFilter(method='filter_tea', lookup_expr='in')
name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
min_age = django_filters.NumberFilter(field_name='age', lookup_expr='gt')
max_age = django_filters.NumberFilter(field_name='age', lookup_expr='lt')
class Meta:
model = models.Student
fields = ['name', 'tea', 'min_age', 'max_age', 'add_time'] # 允许精准查询的字段
search_fields = ['name', ] # 允许模糊查询的字段,上面需要定义
def filter_tea(self, queryset, name, value):
value_list = list(filter(None, value.split(",")))
order_ids = models.Student.objects.filter(tea__in=value_list)
return queryset.filter(id__in=order_ids)
ser:
# coding:utf-8
from rest_framework import serializers
from api import models
class getUserListSerializer(serializers.ModelSerializer):
'''student模型序列化'''
# teaname = serializers.CharField(label="老师姓名", source="tea.name")
# motto = serializers.CharField(label="老师姓名", source="tea.motto")
# days_since_joined = serializers.SerializerMethodField()
class Meta:
model = models.Student
fields = '__all__'
# depth = 1 # 向下取的深度
# 方法写法:get_ + 字段
def get_days_since_joined(self, obj):
# obj指这个model的对象
return '%s-24' % obj.name
4、请求路由列表。
http://127.0.0.1:8000/api/student/read/?name=zh&tea=&add_time=2019-07-10&min_age=1&max_age=55 GET
http://127.0.0.1:8000/api/student/?name=&tea=&add_time=2019-07-10&min_age=1&max_age=55 GET
http://127.0.0.1:8000/api/student/ POST
http://127.0.0.1:8000/api/student/add/ POST
http://127.0.0.1:8000/api/student/1/ PUT
http://127.0.0.1:8000/api/student/a/edit/ PUT
两种方法比较:
router.register(.....)这种方法相比于url,可以少些很多路由,直接在方法中用@action定义就行。
上一篇: 路由Routers
下一篇: DRF03--视图、视图集、路由
推荐阅读
-
写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用
-
drf-03-2个视图基类(APIView,GenericAPIView)、5个视图扩展类、GenericAPIView的视图子类、视图集基类ViewSet、常用视图集父类、路由Routers
-
Django DRF routers路由使用
-
Django(46)drf序列化类的使用(ModelSerializer)
-
django-drf框架自带的路由以及最简化的视图
-
Django框架的使用教程--路由-请求-响应[四]
-
(django)6路由基本使用
-
Django框架的使用教程路由请求响应的方法
-
Django 路由系统URLconf的使用
-
DRF跨域后端解决之django-cors-headers的使用