Django DRF routers路由使用

代码下载:利用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定义就行。

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值