Django前后端分离——drf
Posted 凡大哥随笔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django前后端分离——drf相关的知识,希望对你有一定的参考价值。
Django REST Framework,又称drf,是一个构建API的强大工具,
它只返回前端所需的数据,不再渲染html页面。
这样做的好处:一个接口可供WEB/APP/小程序多端同时使用。
下面我用几个实例来展示如何使用drf:
一、环境搭建
1、cmd安装drf
pip install djangorestframework
2、搭建django框架,
在settings.py里添加'rest_framework'
3、添加urls:
from django.urls import path
from users import views
urlpatterns = [
path('list/', views.list, name='list'),
path('list2/', views.list2View.as_view(), name='list2'),
path('list3/', views.list3View.as_view(), name='list3'),
path('list3BySlug/', views.list3BySlugView.as_view(), name='list3BySlug'),
path('list4/', views.list4View.as_view(), name='list4'),
path('list5/', views.list5View.as_view(), name='list5'),
path('list6/', views.list6View.as_view(), name='list6'),
]
二、最简单的接口,不依赖任何工具
1、views:
def list(request):
user_list = ['wufan','zhengxuesong']
return HttpResponse(json.dumps(user_list))
2、请求:http://127.0.0.1:8000/users/list/
返回用例列表:
三、类视图接口
1、views:
class list2View(View):
def get(self, request, *args, **kwargs):
return HttpResponse('GET')
def post(self, request, *args, **kwargs):
return HttpResponse('POST')
2、get请求:http://127.0.0.1:8000/users/list2/
3、post请求:http://127.0.0.1:8000/users/list2/
四、APIView视图,需求自己写get或post方法
1、创建一个Category的模型
class Category(models.Model):
name = models.CharField("分类名称", max_length=200, db_index=True)
slug = models.SlugField("分类链接", max_length=200, db_index=True, unique=True)
2、通过ModelSerializer创建一个Category的序列化器
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category # 要序列化的模型
fields = '__all__' # 全部字段
# fields = ['name'] # 自定义包含字段
# exclude = ['id','name'] #排除某些字段
3、views:
class list3View(APIView):
def get(self, request, *args, **kwargs):
categorys = Category.objects.all()
# 将列表序列化成json字符串返回给前端,列表要加many=True
ser = CategorySerializer(categorys, many=True)
return Response(ser.data)
def post(self, request, *args, **kwargs):
# request.data获取get入参
# request.query_params.get("xx") 获取post入参你
# 通过序列化器判断入参是否齐全、有效
ser = CategorySerializer(data=request.data)
if not ser.is_valid():
return Response(ser.errors)
else:
# 从序列化器里取出数据
name = ser.validated_data.get('name')
slug = ser.validated_data.get('slug')
category = Category.objects.create(name=name,slug=slug)
ser2 = CategorySerializer(category)
return Response(ser2.data)
4、post请求127.0.0.1:8000/users/list3/
返回json对象
数据库添加成功:
5、如果入参不传name,序列化器校验失败,返回name不能为空。
如果入参传一个已经存在的slug,返回slug重复,因为model里配置了slug的unique=True。
这样通过序列化器就可以判断model里的参数是否缺漏、或者重复。
6、get请求127.0.0.1:8000/users/list3/,
返回Category列表
7、重写一个序列化器CategorySerializer2,这次我们来手动配置入参的校验。
配置name不能为王者荣耀,slug不能为上官婉儿。
记得修改view里的序列化器。
def category_name_validator(value):
if (value == "王者荣耀"):
raise ValidationError('name不能为王者荣耀')
return value
class CategorySerializer2(serializers.Serializer):
name = serializers.CharField(label='分类名称',validators=[category_name_validator,])
slug = serializers.CharField(label='分类链接',max_length=10)
class Meta:
model = Category # 要序列化的模型
fields = '__all__' # 全部字段
exclude = ['id'] #排除某些字段
def validate_slug(self, value):
if value=='上官婉儿':
raise ValidationError('slug不能为上官婉儿')
return value
重新执行post:如果name为王者荣耀,返回错误,数据库不添加数据。
如果slug为上官婉儿也返回错误:
如果入参都正确返回成功。
注意,返回的参数里没有id了,因为在序列化器里id被我exclude了。
五、APIView视图——通过get传参查询数据
1、view
class list3BySlugView(APIView):
def get(self, request, *args, **kwargs):
slug = request.query_params.get("slug")
category = Category.objects.filter(slug=slug).first()
if category:
ser = CategorySerializer(category)
return Response(ser.data)
else:
return Response("查询结果为空")
2、不传任何参数,请求
127.0.0.1:8000/users/list3BySlug
3、get请求带参数
127.0.0.1:8000/users/list3BySlug?slug=wufantest
六、ListAPIView视图
源码里只有get方法,返回一个list
1、view,非常简单,只有简单2句。
class list4View(ListAPIView):
serializer_class = CategorySerializer
queryset = Category.objects.all()
2、请求,127.0.0.1:8000/users/list4/
七、CreateAPIView视图
源码里只有post方法,返回序列化对象
1、view,CreateAPIView更简单,只用写1句话
class list5View(CreateAPIView):
serializer_class = CategorySerializer2
2、使用CreateAPIView的时候,序列化器里必须覆盖create方法
class CategorySerializer2(serializers.Serializer):
name = serializers.CharField(label='分类名称',validators=[category_name_validator,])
slug = serializers.CharField(label='分类链接',max_length=10)
class Meta:
model = Category # 要序列化的模型
fields = '__all__' # 全部字段
exclude = ['id'] #排除某些字段
def validate_slug(self, value):
if value=='上官婉儿':
raise ValidationError('slug不能为上官婉儿')
return value
def create(self, validate_data):
user = Category.objects.create(**validate_data)
return user
3、请求post,127.0.0.1:8000/users/list5/,数据库保存成功
八、有同时实现get和post的视图吗?
当然有,ListCreateAPIView,具体就不展示了
class list6View(ListCreateAPIView):
serializer_class = CategorySerializer2
queryset = Category.objects.all()
九、其他
最近在写微信小程序的API,顺便把日报系统的代码也进行了前后端分离。
学习drf并不难,难的是把它总结成系统的知识点,并让其他人看得懂。
总结过程很辛苦,发际线虽然向后移了,但我也更强了
后面计划分享小程序的学习过程,欢迎继续关注。
以上是关于Django前后端分离——drf的主要内容,如果未能解决你的问题,请参考以下文章