drf入门使用笔记

简述

djangorestframework(后面简称为drf)框架,是基于django框架的一个符合restful模式的工具。
此随笔为简单入门的讲解。不过需要大家对django 框架有一定了解。
此篇随笔不是简单的介绍drf使用方法,而是对drf和django对于简单api 开发代码的对比和层层深入,以此来体现出drf对代码的优化。
随笔以项目目录结构为顺序讲解。阅读的时候,需要上下对照。注意各个类名的区别。
每个模块的最后一部分内容,就是drf对代码的终极优化形态。
随笔根据b站学习视频整理。视频链接https://www.bilibili.com/video/BV1k5411p7Kp/?spm_id_from=333.788.videocard.1
在此,感谢老师无私分享视频。
希望笔记对大家有所帮助。有任何纰漏,敬请指正。

安装

pip install djangorestframework

注册

在django.settings 中,把rest_framework 当做一个APP来注册。

INSTALLED_APPS=[
      'rest_framework',
]

model

from django.db import models

class BookInfo(models.Model):
      btitile = models.CharField(max_length=20, verbose_name='名称')
      bpug_date = models.DateField(verbose_name='发布日期')
      bread = models.IntegerField(default=0, verbose_name='阅读量')
      bcomment = models.IntegerField(default=0, verbose_name='评论量')
      is_delete = models.BooleanField(defult=False, verbose_name-'逻辑删除')

      class meta:
            db_table = 'db_books'
            verbose_name = '图书'
            verbose_name_plural = verbose_name
           
      def __str__(self):
            return self.btitle

class HeroInfo(models.Model):
      GENDER_CHOICES = (
            (0, 'female'),
            (1, 'male')
      )
      hname = models.CharField(max_length=20, verbose_name='名称')
      hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
      hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息')
      hbook = models.ForeignKey(BookInfo, on_delete=models.CASSADE, verbose_name='图书')  # 外键
      is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')
      
      class meta:
            db_table = 'db_heros'
            verbose_name = '英雄'
             verbose_name_plural = verbose_name
           
      def __str__(self):
            return self.hname

序列化serializer

序列化器

这部分主要是给大家看一下序列化器的一个基本内容,让大家对序列化器有一个概念了解。真正在使用的时候,是使用模型序列化器,在下面会说到。

作用

  • 将django中的model对象转换成JSON字符串,这个过程被叫做序列化
  • 将其他格式(如dict,JSON,XML等)转换为程序中的数据,如将JSON装换成model,这个过程被称为反序列化。反序列化的时候,一般需要进行数据校验、入库等操作。

定义序列化器(用于数据转换、校验)

序列化器,一般写在 serializers.py 文件中。遵循如下原则:
  • 定义类,需要继承自Serializer
  • 和model类,字段名字保持一致。
  • 和model类,字段类型保持一致。
  • 和model类,字段选项保持一致(即字段设置参数)。
反序列化,一般分为两部分,校验和入库。

校验:
在view中使用serializer.is_valid(raise_exception=True)调用校验。raise_exception选项是判定是否抛出异常。

  • 字段类型校验:
    * CharField
    * DateField
    * IntegerField
    * 等等
  • 字段选项校验:
    * max_length
    * min_length
    * required:默认是True 必须要传参,除非设置required=False 或 default=xx 或 read_only
    * read_only:只读,设置该选项的字段,只序列化,不进行反序列化。
  • 单字段校验(def方法):
# 固定格式:
def validate_btitle(self, value):  # validate_xxxx(self, value)   value就是传入的btitle值
      # 各种校验逻辑
      if xxxxxx:
            raise serializers.ValidationError('校验错误信息')  # 一定是raise ,return就表明校验通过了。
      return value
  • 多字段校验(def方法):
def validate(self, attrs):  # attrs就是传入进来的dict_data
      # 多用于对多个字段之间进行关系校验。也可以对单个字段进行校验,灵活使用。
      # eg:value1 < value2 时,raise 异常
      value1 = attrs['value1']
      value2 = attrs['value2']
      if value1 < value2:
            raise serializers.ValidationError('校验错误信息')  # 一定是raise ,return就表明校验通过了。
      return attrs
  • 自定义校验(def方法):
    自定义校验方法放置在序列化器类的外面,为独立的静态方法。
    见下面序列化器主代码中的check_bpub_date()方法。
    自定义校验使用较少,多以被单字段校验方法替代。

入库:
在view 中调用 serializer.save()方法

  • 创建新的对象create
    必须在序列化器中重写create()方法。在实例化serializer的时候,需要把数据传入。
def create(self, validated_data):  # validated_data 校验成功之后的数据。
      # 1.创建对象
      book = BookInfo.objects.create(**validated_data)
      # 3.返回
      return book
      
  • 更新对象的update
    更新对象在使用的时候,与create不同的是,update 需要在实例化serializer时,传递instance 即需要把要更新的objects传递给序列化器。具体使用见views中代码。
    update 方法也需要在序列化器中重写。
def update(self, instance, validated_data):  # instance 传递进来的模型对象object 。validated_data 校验成功之后的数据。
      # 1.更新数据
      instance.btitle = validated_data['btitle']
      instance.bpug_date = validated_data['bpug_date']
      instance.bread = validated_data['bread']
      instance.bcomment = validated_data['bcomment']
      # 2.入库
      instance.save()
      # .返回
      return instance
序列化器代码
from rest_framework import serializers

def check_bpub_date(value):
      # 自定义校验方法。需要在所校验的字段中,添加 validator=[check_bpub_date] 选项。
      if value.year < 2018:
            raise serializers.ValidationError('校验错误信息')
      return value

class BookInfoSerializer(serializers.Serializer):
      id = serializers.IntegerField(label='id', read_only=True)
      btitile = serializers.CharField(max_length=20, label='名称')
      bpug_date = serializers.DateField(label='发布日期', validator=[check_bpub_date])  # 其中validator=[check_bpub_date]选项为调用自定义校验方法。
      bread = serializers.IntegerField(default=0, label='阅读量')
      bcomment = serializers.IntegerField(default=0, label='评论量')
      is_delete = serializers.BooleanField(default=False, label='逻辑删除')

      # 1.hero model 关联book的外键,显示所有关联的hero PrimaryKey 信息。(即,一方查多方)。需要many=True
      heroinfo_set = serializers.PrimaryKeyRelatedField(readonly=True, many=True)

      # 2.显示所有关联的hero __str__ 返回值信息。
      heroinfo_set = serializers.StringRelatedField(readonly=True, many=True)

      # 3.显示所有关联的hero PrimaryKey 信息。
      heroinfo_set = HeroInfoSerializer()

      def create(self, validated_data):  # validated_data 校验成功之后的数据。
            # 1.创建对象
            book = BookInfo.objects.create(**validated_data)
            # 3.返回
            return book

      def update(self, instance, validated_data):  # instance 传递进来的模型对象object 。validated_data 校验成功之后的数据。
            # 1.更新数据
            instance.btitle = validated_data['btitle']
            instance.bpug_date = validated_data['bpug_date']
            instance.bread = validated_data['bread']
            instance.bcomment = validated_data['bcomment']
            # 2.入库
            instance.save()
            # .返回
            return instance
class HeroInfoSerializer(serializers.Serializer):
      GENDER_CHOICES = (
            (0, 'female'),
            (1, 'male')
      )
      id = serializers.IntegerField(label='id', read_only=True)
      hname = serializers.CharField(max_length=20, label='名称')
      hgender = serializers.ChoiceField(choices=GENDER_CHOICES, label='性别', required=False)
      hcomment = serializers.IntegerField(max_length=200, label='描述信息', required=False, allow_null=True)
      
      # 外键关联字段的处理
      # 1.显示关联信息的主键。设置 read_only 或 queryset。
      hbook = serializers.PrimaryKeyRelatedField(read_only=True)  # serializers.PrimaryKeyRelatedField(queryset=BookInfo.objects.all())
      # 2.关联信息显示关联model里的__str__方法返回值
      hbook = serializers.StringRelatedField(read_only=True)
      # 3.使用关联model的序列化器,显示其序列化器中配置信息。会以字典形式体现(OrderedDict)。
      hbook = BookInfoSerializer()

      is_delete = serializers.BooleanField(default=False, label='逻辑删除')

model序列化器

上面说到的序列化器,其实只是说明了序列化的作用和其中的原理,并没有体现出restframework框架对于项目的真正优化。
模型序列化器,是真正drf框架的魅力所在。(所谓魅力,不过就是别人封装好了方法,而我们只需要简单调用。--!)

  • 根据Model自动生成字段
  • ModelSerializer提供了create方法和update方法。不需要再重写。
from rest_framework import serializers
from .models import BookInfo
# 1.定义书籍模型类序列化器。
class BookModelSerializer(serializers.ModelSerializer):

      mobile = serializers.CharField(max_length=11, min_lengeh=11, label='手机号')  # 当下面meta中根据模型类自动生成的字段不满足我们的需求时,可以再次继续手动添加字段。比如  验证码, 这个字段不需要存储(即model中不需要此字段),但是需要校验。

      class Meta:
            model = BookInfo  # 参考模型类生成字段
            fields = "__all__"  # 自动生成所有字段

            # 如果想生成指定字段,则可以使用元组或列表。所选择字段必须包含在model中。
            # fields = ['id', 'btitle']

            # 设置只读字段。(read_only 只能序列化,不能反序列化)。不设置,默认只有id为read_only。
            # read_only_fields = ['btitle']
            
            # 为生成的字段添加额外约束。
            # extra_kwargs = {"bread":{"max_value": 99999, "min_value":0}}

通过对比model序列化器和普通的序列化器,我们可以看到,drf把我们常用的功能,都已经封装好,大大提高了我们的开发效率。

view

视图集(views 增删改查流程封装的,未使用drf APIView)

序列化:

  • 获取对象
  • 创建序列化器,instance表示要序列化的对象
  • 转换对象

反序列化:

  • 获取数据:从前端获取的json数据,转换成字典dict。
  • 创建序列化器
from .serializers import BookInfoSerializer
from .models import BookInfo

# 单个对象序列化方法
book = BookInfo.objects.get(id=1)
serializer = BookInfoSerializer(instance=book)
serializer.data  # 序列化结果

# 列表对象序列化方法
books = BookInfo.objects.all()
serializer = BookInfoSerializer(instance=books, many=True)
serializer.data

# 反序列化,校验
book_dict = {
      'btitle': 'HP',
      'bpug_date': '2001-1-1',
      'bread': 10,
      'bcomment': 5
}
serializer = BookInfoSerializer(data=book_dict)
serializer.is_valid()
serializer.data

# 反序列化,入库(create)
book_dict = {
      'btitle': 'HP',
      'bpug_date': '2001-1-1',
      'bread': 10,
      'bcomment': 5
}
serializer = BookInfoSerializer(data=book_dict)
serializer.is_valid()
serializer.save()

# 反序列化,入库(update)
book = BookInfo.objects.get(id=1)
book_dict = {
      'btitle': 'HP',
      'bpug_date': '2001-1-1',
      'bread': 10,
      'bcomment': 5
}
serializer = BookInfoSerializer(instance=book, data=book_dict)
serializer.is_valid()
serializer.save()

cbv模式代码示例

from django.views import View
from .models import *
from django import http
import json
from .serializers import *

class BookInfoView(View):
      def get(self, request):
            books = BookInfo.objects.all()

            # 序列化
            serializer = BookInfoSerializer(instance=books, many=True)
            return http.JsonResponse(serializer.data, safe=False)  # safe=False 可以安全返回非字典

      def post(self, request):
            # 1.获取参数
            dict_data = json.loads(request.body.decode())
            # 2.数据入库
            book = BookInfo.objects.create(**dict_data)
            # 3.序列化
            serializer = BookInfoSerializer(instance=book)
      
            return http.JsonResponse(serializer.data, safe=False)

class BookInfoDetailView(View):
      def get(self, request, **kwargs):
            pk = kwargs.get('pk', '')
            book = BookInfo.objects.get(pk=pk)

            # 序列化
            serializer = BookInfoSerializer(instance=book)
            return http.JsonResponse(serializer.data, safe=False)

      def put(self, request, **kwargs):
            pk = kwargs.get('pk', '')
            book = BookInfo.objects.get(pk=pk)
            dict_data = json.loads(request.body.decode())
            
            BookInfo.objescts.filter(pk=pk).update(**dict_data)
            book = BookInfo.objescts.get(pk=pk)

            # 序列化
            serializer = BookInfoSerializer(instance=book)
            return http.JsonResponse(serializer.data, safe=False)

      def delete(self, request, **kwargs):
            pk = kwargs.get('pk', '')
            book = BookInfo.objescts.get(pk=pk)
            book.delete()
            return http.JsonResponse(status=204)

drf APIView(drf提供的view)

特点:

  • 集成自View
  • 提供了独立的request对象
  • 提供了独立的response对象
  • 提供了独立的身份认证,权限,限流等功能。

request

view获取数据方式:
GET:request.GET
POST:request.POST 表单数据
request.body json数据

APIView获取数据方式:
GET:request.query_params
POST:request.data

response

  • 使用一个response类,就可以替代django view中的各种类型的Response(HttpResponse,JsonResponse..)
  • 可以配合状态吗status 使用。drf对所有的http状态码 提供了含义名称(如 404 为 HTTP_404_NOT_FOUND)。具体可见 rest_framework.status.py

使用 model序列化器 和 APIView 对 View进行改写。

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import BookInfo
from .serializers import BookModelSerializer


# 列表视图
class BookListAPIView(APIView):
      def get(self, request):
            # 查询所有对象
            books = BookInfo.objects.all()
            # 将对象列表转化为字典列表
            serializer = BookInfoModelSerializer(instance=books, many=True)
            # 返回响应
            return Response(serializer.data)
      
      def post(self, request):
            # 获取参数
            data_dict = request.data
            # 创建序列化器
            serializer = BookInfoModelSerializer(data=data_dict)
            # 校验,入库
            serializer.is_valid(raise_exception = True)
            serializer.save()
            # 返回响应
            return Response(serializer.data, status=status.HTTP_201_CREATED)


# 详情视图
class BookDetailAPIView(APIView):
      def get(self, request, **kwargs):
            # 获取对象数据
            book_id = kwargs.get('book_id', '')
            book = BookInfo.objects.get(id=book_id)
            # 创建序列化器对象
            serializer = BookInfoModelSerializer(instance=book)
            # 返回响应
            return Response(serializer.data)

      def put(self, request, **kwargs):
            data_dict = request.data
            # 获取对象数据
            book_id = kwargs.get('book_id', '')
            book = BookInfo.objects.get(id=book_id)
            # 创建序列化器对象
            serializer = BookInfoModelSerializer(instance=book, data=data_dict)
            # 检验,入库
            serializer.is_valid(raise_exception=True)
            serializer.save()
            # 返回响应
            return Response(serializer.data, status=status.HTTP_201_CREATED)

      def delete(self, request, **kwargs):
            pk = kwargs.get('book_id', '')
            book = BookInfo.objescts.get(pk=pk)
            book.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)

二级视图GenericAPIView(增强代码复用性)

GenericAPIView 继承自APIView类,为列表视图和详情视图,添加了常用的方法和属性。通过这些方法和属性,可以对代码进行复用,减少重复代码。

  * 方法:
        get_queryset()
        get_serializer()
        get_object():获取单个对象的方法,注意设置lookup_url_kwargs或lookup_field.不设置的话,默认使用lookup_field='pk'。
  * 属性: 
        queryset
        serializer_class
        lookup_url_kwarg:默认为None。这个属性对应url中带入的参数名。get_object()方法会根据这个属性名获取到url中所传递的值,然后到queryset中获取到单个对象。
        lookup_field:默认是pk。与lookup_url_kwarg有部分作用重复,默认先判断lookup_url_kwarg。唯一与lookup_url_kwarg不同的是,由于会根据lookup_field操作orm,所以这个值必须是model中有的字段。
# from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status
from .models import BookInfo
from .serializers import BookModelSerializer

# 列表视图
class BookListGenericAPIView(GenericAPIView):
      
      # 提供公共的属性
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoModelSerializer

      def get(self, request):
            # 查询所有对象(两种方式)
            books = self.get_queryset()  # 或直接 books = self.queryset
            
            # 将对象列表转化为字典列表 (三种方式)
            # serializer = self.serializer_class(instance=books, many=True)
            # serializer = self.get_serializer_class()(instance=books, many=True)  
            serializer = self.get_serializer(instance=books, many=True)  

            # 返回响应
            return Response(serializer.data)
      
      def post(self, request):
            # 获取参数
            data_dict = request.data
            # 创建序列化器
            serializer = self.get_serializer(data=data_dict)
            # 校验,入库
            serializer.is_valid(raise_exception = True)
            serializer.save()
            # 返回响应
            return Response(serializer.data, status=status.HTTP_201_CREATED)

# 详情视图
class BookDetailGenericAPIView(GenericAPIView):

      # 提供公共的属性
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoModelSerializer
      lookup_url_kwarg = 'book_id'

      def get(self, request, **kwargs):
            # 获取对象数据
            book = self.get_object()  # 根据pk到query_set中取出对象。
            # 创建序列化器对象
            serializer = self.get_serializer(instance=book)
            # 返回响应
            return Response(serializer.data)

      def put(self, request, **kwargs):
            data_dict = request.data
            # 获取对象数据
            book = self.get_object()
            # 创建序列化器对象
            serializer = self.get_serializer(instance=book, data=data_dict)
            # 检验,入库
            serializer.is_valid(raise_exception=True)
            serializer.save()
            # 返回响应
            return Response(serializer.data, status=status.HTTP_201_CREATED)

      def delete(self, request, **kwargs):
            book = self.get_object()
            book.delete()
            return Response(status=status.HTTP_204_NO_CONTENT) 

mixin类

  • mixin类提供用于基本视图行为(列表视图,详情视图)的操作。(其实就是提供了get,post,put,delete等通用方法)
  • 配合二级视图GenericAPIView使用。
类名称 提供方法 功能
ListModelMixin list 查询所有的数据
CreateModelMixin create 创建单个对象
RetrieveModelMixin retrieve 获取单个对象
UpdateModelMixin update 更新单个对象
DestroyModelMixin destory 删除单个对象

Mixin和GenericAPIView使用

from rest_framework.generics import GenericAPIView
from rest_framework.mixin import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
from .models import BookInfo
from .serializers import BookModelSerializer

# 列表视图
class BookListMixinGenericAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
      
      # 提供公共的属性
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoModelSerializer

      def get(self, request):
           return self.list(request)
      
      def post(self, request):
           return self.create(request)

# 详情视图
class BookDetailMixinGenericAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):

      # 提供公共的属性
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoModelSerializer
      lookup_url_kwarg = 'book_id'

      def get(self, request, **kwargs):
            return self.retrieve(reqyest)

      def put(self, request, **kwargs):
            return self.update(request)

      def delete(self, request, **kwargs):
            return self.destroy(request)

三级视图

如果没有大量的自定义行为,可以使用三级视图解决。
常见的三级视图:

类名称 父类 提供方法 作用
CreateAPIView GenericAPIView,CreateModelMixin post 创建单个对象
ListAPIView GenericAPIView, ListModelMixin get 查询所有数据
RetrieveAPIView GenericAPIView,RetrieveModelMixin get 获取单个对象
DestroyAPIView GenericAPIView,DestroyModelMixin delete 删除单个对象
UpdateAPIView GenericAPIView,UpdateModelMixin put,patch 更新单个对象
框架中还有其他组合,可自行查看
from rest_framework.generics import ListAPIView, CreateAPIView, RetrieveAPIView, DestroyAPIView, UpdateAPIView
from .models import BookInfo
from .serializers import BookModelSerializer

# 列表视图
class BookListView(ListAPIView, CreateAPIView):
      
      # 提供公共的属性
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoModelSerializer

# 详情视图
class BookDetailView(RetrieveAPIView, DestroyAPIView, UpdateAPIView):

      # 提供公共的属性
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoModelSerializer
      # lookup_url_kwarg = 'book_id'  # 如果url中使用pk,此行代码可去掉。

视图集

  • 可以将一组相关的操作,放在一个类中进行完成。(比如上面说到的列表视图和详情视图,都有get方法,无法合并到一个类中。)
  • 不提供get,post方法,使用retrieve,create方法来替代。
  • 可以将标准请求方式(get,post...)和mixin中的方法做映射

常见的视图集

类名称 父类 作用
ViewSet APIView,ViewSetMixin 可以做路由映射
GenericViewSet GenericAPIView,ViewSetMixin 可以做路由映射,可以使用二级视图的属性和方法
ModelViewSet GenericAPIView,5个mixin类 所有的增删改查功能,可以使用二级视图的属性和方法
ReadOnlyModelViewSet GenericAPIView,RetrieveModelMixin,ListModelMixin 获取单个和所有数据,可以使用二级视图的属性和方法

ViewSet获取所有和单个

from django.shortcus import get_object_or_404
from .serializers import BookInfoModelSerializer
from rest_framework import viewsets
from rest_framework.response import Response

class BooksViewSet(viewsets.ViewSet):
      def list(self, request):
            books = BookInfo.objects.all()
            serializer = BookInfoModelSerializer(instance=books, many=True)
            return Response(serializer.data)

      def retrieve(self, request, pk=None):
            books = BookInfo.objects.all()
            book = get_object_or_404(books, pk=pk)
            serializer = BookInfoModelSerializer(instance=book)
            return Response(serializer.data)

url 中做映射

*************** 忽略部分代码
urlpatterns = [
      url(r'^viewset/$', views.BooksViewSet.as_view({'get': 'list'})),
      url(r'^viewset/(?p<pk>\d+)/$', views.BooksViewSet.as_view({'get': 'retrieve'})),
]
************** 忽略部分代码

ReadOnlyModelViewSet获取所有和单个对象

from rest_framework.viewsets import ReadOnlyModelViewSet
from .serializers import BookInfoModelSerializer

class BooksReadOnlyModelViewSet(ReadOnlyModelViewSet):
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoModelSerializer

url 中做映射

*************** 忽略部分代码
urlpatterns = [
      url(r'^readonly_viewset/$', views.BooksReadOnlyModelViewSet.as_view({'get': 'list'})),
      url(r'^readonly_viewset/(?p<pk>\d+)/$', views.BooksReadOnlyModelViewSet.as_view({'get': 'retrieve'})),
]
************** 忽略部分代码

ModelViewSet实现列表视图和详情视图全部功能

from rest_framework.viewsets import ModelViewSet
from .serializers import BookInfoModelSerializer

class BooksModelViewSet(ModelViewSet):
      queryset = BookInfo.objects.all()
      serializer_class = BookInfoModelSerializer

url 中做映射

*************** 忽略部分代码
urlpatterns = [
      url(r'^model_viewset/$', views.BooksModelViewSet.as_view({'get': 'list', 'post':'create'})),
      url(r'^model_viewset/(?p<pk>\d+)/$', views.BooksModelViewSet.as_view({'get': 'retrieve', 'put':'update', 'delete':'destroy'})),
]
************** 忽略部分代码

视图集做额外动作(方法)。

在视图集中编写符合需求的方法,并在路由中做对应映射。
当需求要求局部更新,在创建序列化器的时候,需要传入 partial=True 参数。否则不能通过校验。
自定义的方法需要加上装饰器才能被drf自动生成路由
装饰器:

from rest_framework.decorators import action
@action(methods=['GET'], detail=False)  # methods 是这个方法需要什么类型的请求方式,detail 决定需不需要传参。所传递的参数,需要在方法中写明。
def chargename(self, request[, 参数]):
  pass

url路由

可以通过DefaultRouter和SimpleRouter两个类来自动生成路由。

DefaultRouter

from django.conf.urls import url
from . import views
from rest_framework.routers import DefaultRouter

urlpatterns = [
]

# drf路由
router = DefaultRouter()
router.register(r'books',views.BookInfoModelViewSet,base_name='books')  # books 是路径前缀。
urlpatterns += router.urls

DefaultRouter会自动生成3组共6个url路径,分别对应列表路径,详情路径,根路径。每种都提供json类型数据和带html的text类型数据两种,可以直观在浏览器中,通过对url结尾处添加.json 来直接查看json数据。不添加.json 则为带html的页面。
使用drf可以自动根据前端需要的类型,返回对应格式的数据。请求的时候,在请求头中标记 accept 即可。

SimpleRouter

from django.conf.urls import url
from . import views
from rest_framework.routers import SimpleRouter

urlpatterns = [
]

# drf路由
router = SimpleRouter()
router.register(r'books',views.BookInfoModelViewSet,base_name='books')  # books 是路径前缀。
urlpatterns += router.urls

SimpleRouter会自动生成2个url路径,分别对应列表路径,详情路径。
使用drf可以自动根据前端需要的类型,返回对应格式的数据。请求的时候,在请求头中标记 accept 即可。

posted @ 2021-02-07 14:15  dsprain  阅读(210)  评论(0)    收藏  举报