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 即可。

浙公网安备 33010602011771号