Rest Framework:三、HyperlinkedidentityField用法
一、HyperlinkedIdentityField(用的很少)
环境配置:
1、使django支持mysql(不再介绍)
2、settings.py文件INSTALLED_APPS字段中添加"rest_framework"
urls.py
url(r'^books/',views.Books.as_view()),url(r'^publish/(?P<pk>\d+)',views.Publish.as_view(),name='ttt'),
app01/server.py
fromrest_frameworkimportserializersclassAuthorSerializer(serializers.Serializer):nid=serializers.CharField()name=serializers.CharField()age=serializers.CharField()classBookSerializer(serializers.Serializer):name=serializers.CharField()#publish=serializers.CharField()#把名字换成链接地址,#view_name:路由的别名#lookup_field:根据表指定字段,来拼路径,生成链接#lookup_url_kwarg:默认是pk,(urls.py中的publish/(?P<pk>\d+),指定的pk)可以不写,反向解析有名分组的名字。publish=serializers.HyperlinkedIdentityField(view_name='ttt',lookup_field='publish_id',lookup_url_kwarg='pk')
views.py
fromdjango.shortcutsimportHttpResponse,renderfromrest_framework.viewsimportAPIViewfromdjango.httpimportJsonResponsefromapp01importmodelsfromapp01.serverimportBookSerializer#Createyourviewshere.classBooks(APIView):defget(self,request,*args,**kwargs):ret=models.Book.objects.all()book_ser=BookSerializer(ret,many=True,context={'request':request})print(book_ser.data)returnJsonResponse(book_ser.data,safe=False)classPublish(APIView):defget(self,request,*args,**kwargs):returnHttpResponse('ok')
models.py
fromdjango.dbimportmodels#Createyourmodelshere.classBook(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)price=models.DecimalField(max_digits=5,decimal_places=2)publish_date=models.DateField()#外键对应数据库表中的字段名后面会自动加"_id"#on_delete=models.CASCADE级联删除publish=models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)#ManyToManyField自动创建第三张表,本表名_到你对应多的表名名字,自动帮你把表名转小写authors=models.ManyToManyField(to='Author')def__str__(self):returnself.nameclassAuthor(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)age=models.IntegerField()author_detail=models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE)classAuthorDatail(models.Model):nid=models.AutoField(primary_key=True)telephone=models.BigIntegerField()birthday=models.DateField()addr=models.CharField(max_length=64)classPublish(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)city=models.CharField(max_length=32)email=models.EmailField()def__str__(self):returnself.namedeftest(self):returnself.email
最后使用:
python3 manage makemigrations
python3 manage migrate
数据库的表中添加数据:
使用postman验证:
总结:
-1 publish = serializers.HyperlinkedIdentityField(view_name='ttt',lookup_field='publish_id',lookup_url_kwarg='pky')
-2 view_name:路由的别名,lookup_field:根据表的哪个字段,来拼路径,lookup_url_kwarg:反向解析有名分组的名字
-3 写路由:url(r'^publish/(?P<pky>\d+)', views.Publish.as_view(),name='ttt'),
-4 实例化序列化类的时候,需要把request对象传过去
book_ser=BookSerializer(ret,many=True,context={'request': request})
二、序列化组件的反序列化和保存
环境配置:
1、使django支持mysql(不再介绍)
2、settings.py文件INSTALLED_APPS字段中添加"rest_framework"
urls.py
url(r'^books/',views.Books.as_view()),url(r'^publish/(?P<pk>\d+)',views.Publish.as_view(),name='ttt'),
models.py
fromdjango.dbimportmodels#Createyourmodelshere.classBook(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)price=models.DecimalField(max_digits=5,decimal_places=2)publish_date=models.DateField()#外键对应数据库表中的字段名后面会自动加"_id"#on_delete=models.CASCADE级联删除publish=models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)#ManyToManyField自动创建第三张表,本表名_到你对应多的表名名字,自动帮你把表名转小写authors=models.ManyToManyField(to='Author')def__str__(self):returnself.nameclassAuthor(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)age=models.IntegerField()author_detail=models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE)classAuthorDatail(models.Model):nid=models.AutoField(primary_key=True)telephone=models.BigIntegerField()birthday=models.DateField()addr=models.CharField(max_length=64)classPublish(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)city=models.CharField(max_length=32)email=models.EmailField()def__str__(self):returnself.namedeftest(self):returnself.email
app01/server.py
fromrest_frameworkimportserializersfromapp01importmodelsclassAuthorSerializer(serializers.Serializer):nid=serializers.CharField()name=serializers.CharField()age=serializers.CharField()classBookSerializer(serializers.ModelSerializer):classMeta:model=models.Bookfields='__all__'authors=serializers.CharField(required=False)
views.py
fromdjango.shortcutsimportHttpResponse,renderfromrest_framework.viewsimportAPIViewfromdjango.httpimportJsonResponsefromapp01importmodelsfromapp01.serverimportBookSerializer#Createyourviewshere.classBooks(APIView):defget(self,request,*args,**kwargs):ret=models.Book.objects.all()book_ser=BookSerializer(ret,many=True,context={'request':request})print(book_ser.data)returnJsonResponse(book_ser.data,safe=False)defpost(self,request,*args,**kwargs):#前端传过来的数据从data中取#用序列化类的数据校验#data参数,是要校验的数据response={'status':100,'msg':'成功'}ser=BookSerializer(data=request.data)ifser.is_valid():#如果数据校验通过,is_valid是True#保存到数据库,ser是谁的对象?继承了ModelSerializer的类的对象ser.save()else:response['status']=101response['msg']=ser.errorsreturnJsonResponse(response,safe=False)classPublish(APIView):defget(self,request,*args,**kwargs):returnHttpResponse('ok')
使用postman提交数据验证:
{
"name":"水浒传",
"price":"23.00",
"publish_date":"2018-12-01",
"publish":1
}
app01/server.py
#其他一样,只是加了这一段,验证
#name = serializers.CharField(min_length=3, error_messages={'required': '该字段必填','min_length':'最短3位'})
fromrest_frameworkimportserializersfromapp01importmodelsclassAuthorSerializer(serializers.Serializer):nid=serializers.CharField()name=serializers.CharField()age=serializers.CharField()classBookSerializer(serializers.ModelSerializer):classMeta:model=models.Bookfields='__all__'name=serializers.CharField(min_length=3,error_messages={'required':'该字段必填','min_length':'最短3位'})authors=serializers.CharField(required=False)
# 使用postman post提交数据验证
三、序列化组件修改功能
环境与上面一样
urls.py
url(r'^books/$',views.Books.as_view()),url(r'^books/(?P<pk>\d+)',views.BooksDetail.as_view()),
app01/server.py
fromrest_frameworkimportserializersfromapp01importmodelsclassAuthorSerializer(serializers.Serializer):nid=serializers.CharField()name=serializers.CharField()age=serializers.CharField()classBookSerializer(serializers.ModelSerializer):classMeta:model=models.Bookfields='__all__'name=serializers.CharField(min_length=3,error_messages={'required':'该字段必填','min_length':'最短3位'})authors=serializers.CharField(required=False)
views.py
fromdjango.shortcutsimportHttpResponse,renderfromrest_framework.viewsimportAPIViewfromdjango.httpimportJsonResponsefromapp01importmodelsfromapp01.serverimportBookSerializer#Createyourviewshere.classBooksDetail(APIView):defget(self,request,pk):response={'status':100,'msg':'成功'}ret=models.Book.objects.all().filter(pk=pk).first()ifret:#序列化单条,many=Falsebook_ser=BookSerializer(ret,many=False)print(book_ser.data)response['data']=book_ser.dataelse:response['status']=101response['msg']='查询不存在'returnJsonResponse(response,safe=False)defput(self,request,pk):response={'status':100,'msg':'成功'}ret=models.Book.objects.all().filter(pk=pk).first()ifret:#数据校验#传instance和不传instance,传instance的区别#不传instance,调save(),往数据库新增数据#传instance,调save(),修改数据ser=BookSerializer(data=request.data,instance=ret)ifser.is_valid():ser.save()else:response['status']=101response['msg']=ser.errorselse:response['status']=102response['msg']='修改的对象不存在'returnJsonResponse(response,safe=False)classBooks(APIView):defget(self,request,*args,**kwargs):ret=models.Book.objects.all()book_ser=BookSerializer(ret,many=True,context={'request':request})print(book_ser.data)returnJsonResponse(book_ser.data,safe=False)defpost(self,request,*args,**kwargs):#前端传过来的数据从data中取#用序列化类的数据校验#data参数,是要校验的数据response={'status':100,'msg':'成功'}ser=BookSerializer(data=request.data)ifser.is_valid():#如果数据校验通过,is_valid是True#保存到数据库,ser是谁的对象?继承了ModelSerializer的类的对象ser.save()else:response['status']=101response['msg']=ser.errorsreturnJsonResponse(response,safe=False)classPublish(APIView):defget(self,request,*args,**kwargs):returnHttpResponse('ok')
models.py不变
python3 manage makemigrations
python3 manage migrate
使用postman的put请求方式修改数据
数据库查看数据
总结:
-序列化组件的数据校验
-类比forms组件
-字段是否必填,通过required,来控制 authors=serializers.CharField(required=False)
-数据校验,生成一个序列化类的对象
-对象.is_valid()
-新增数据:
-对象.save()
-修改数据:
-在生成对象的时候,需要传instanse=查询出来的对象
-对象.save()
四、序列化组件数据校验功能的钩子函数
-局部
-全局
环境与以上配置一样,只有这个文件不一样。
局部钩子:
app01/server.py
fromrest_frameworkimportserializersfromapp01importmodelsfromrest_framework.exceptionsimportValidationErrorclassAuthorSerializer(serializers.Serializer):nid=serializers.CharField()name=serializers.CharField()age=serializers.CharField()classBookSerializer(serializers.ModelSerializer):classMeta:model=models.Bookfields='__all__'name=serializers.CharField(min_length=3,error_messages={'required':'该字段必填','min_length':'最短3位'})authors=serializers.CharField(required=False)#局部钩子defvalidate_name(self,value):print(value)ifvalue.startswith('sb'):raiseValidationError('不能以sb开头')else:returnvalue
使用postman验证
全局钩子:
app01/server.py
fromrest_frameworkimportserializersfromapp01importmodelsfromrest_framework.exceptionsimportValidationErrorclassAuthorSerializer(serializers.Serializer):nid=serializers.CharField()name=serializers.CharField()age=serializers.CharField()classBookSerializer(serializers.ModelSerializer):classMeta:model=models.Bookfields='__all__'name=serializers.CharField(min_length=3,error_messages={'required':'该字段必填','min_length':'最短3位'})authors=serializers.CharField(required=False)#全局钩子#value是所有效验通过数据的字典defvalidate(self,value):name=value.get('name')price=value.get('price')ifnameandprice:ifstr(name)==str(price):returnvalueelse:raiseValidationError('名字跟价格不相等')returnvalue
使用postman验证:
五、认证组件初始
urls.py
url(r'^books/$',views.Books.as_view()),url(r'^books/(?P<pk>\d+)',views.BooksDetail.as_view()),url(r'^publish/(?P<pk>\d+)',views.Publish.as_view(),name='ttt'),url(r'^login/',views.login.as_view()),
app01/server.py (与之前一样,没改过)
fromrest_frameworkimportserializersfromapp01importmodelsfromrest_framework.exceptionsimportValidationErrorclassAuthorSerializer(serializers.Serializer):nid=serializers.CharField()name=serializers.CharField()age=serializers.CharField()classBookSerializer(serializers.ModelSerializer):classMeta:model=models.Bookfields='__all__'name=serializers.CharField(min_length=3,error_messages={'required':'该字段必填','min_length':'最短3位'})authors=serializers.CharField(required=False)#局部钩子defvalidate_name(self,value):print(value)ifvalue.startswith('sb'):raiseValidationError('不能以sb开头')else:returnvalue#全局钩子#value是所有效验通过数据的字典defvalidate(self,value):name=value.get('name')price=value.get('price')ifnameandprice:ifstr(name)==str(price):returnvalueelse:raiseValidationError('名字跟价格不相等')returnvalue
views.py
fromdjango.shortcutsimportHttpResponse,renderfromrest_framework.viewsimportAPIViewfromdjango.httpimportJsonResponsefromapp01importmodelsfromapp01.serverimportBookSerializer#Createyourviewshere.fromrest_frameworkimportexceptionsclassAuth():defauthenticate(self,request):#请求来的东西都能拿出来#包装后的request对象,请求来的所有东西都能拿出来#如果认证通过,需要返回东西,如果认证不通过,要抛异常token=request.GET.get('token')ret=models.UserToken.objects.filter(token=token).first()#如果有值,说明登录过了,而且带的随机字符串也是正确的ifret:returnNoneelse:#如果没有值,抛异常raiseexceptions.APIException('请登录')fromrest_framework.requestimportRequestclassBooksDetail(APIView):authentication_classes=[Auth]defget(self,request,pk):response={'status':100,'msg':'成功'}ret=models.Book.objects.all().filter(pk=pk).first()ifret:#序列化单条,many=Falsebook_ser=BookSerializer(ret,many=False)print(book_ser.data)response['data']=book_ser.dataelse:response['status']=101response['msg']='查询不存在'returnJsonResponse(response,safe=False)defput(self,request,pk):response={'status':100,'msg':'成功'}ret=models.Book.objects.all().filter(pk=pk).first()ifret:#数据校验#传instance和不传instance,传instance的区别#不传instance,调save(),往数据库新增数据#传instance,调save(),修改数据ser=BookSerializer(data=request.data,instance=ret)ifser.is_valid():ser.save()else:response['status']=101response['msg']=ser.errorselse:response['status']=102response['msg']='修改的对象不存在'returnJsonResponse(response,safe=False)classBooks(APIView):defget(self,request,*args,**kwargs):ret=models.Book.objects.all()book_ser=BookSerializer(ret,many=True,context={'request':request})print(book_ser.data)returnJsonResponse(book_ser.data,safe=False)defpost(self,request,*args,**kwargs):#前端传过来的数据从data中取#用序列化类的数据校验#data参数,是要校验的数据response={'status':100,'msg':'成功'}ser=BookSerializer(data=request.data)ifser.is_valid():#如果数据校验通过,is_valid是True#保存到数据库,ser是谁的对象?继承了ModelSerializer的类的对象ser.save()else:response['status']=101response['msg']=ser.errorsreturnJsonResponse(response,safe=False)classPublish(APIView):defget(self,request,*args,**kwargs):returnHttpResponse('ok')importuuidclasslogin(APIView):defpost(self,request):response={'status':100,'msg':'登录成功'}name=request.data.get('name')pwd=request.data.get('pwd')user=models.UserInfo.objects.filter(name=name,pwd=pwd).first()ifnotuser:response['status']=101response['msg']='用户名密码错误'else:#生成一个随机字符串token=uuid.uuid4()#去数据库保存models.UserToken.objects.create(token=token,user=user)response['token']=tokenreturnJsonResponse(response,safe=False)
models.py
fromdjango.dbimportmodels#Createyourmodelshere.classBook(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)price=models.DecimalField(max_digits=5,decimal_places=2)publish_date=models.DateField()#外键对应数据库表中的字段名后面会自动加"_id"#on_delete=models.CASCADE级联删除publish=models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)#ManyToManyField自动创建第三张表,本表名_到你对应多的表名名字,自动帮你把表名转小写authors=models.ManyToManyField(to='Author')def__str__(self):returnself.nameclassAuthor(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)age=models.IntegerField()author_detail=models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE)classAuthorDatail(models.Model):nid=models.AutoField(primary_key=True)telephone=models.BigIntegerField()birthday=models.DateField()addr=models.CharField(max_length=64)classPublish(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)city=models.CharField(max_length=32)email=models.EmailField()def__str__(self):returnself.namedeftest(self):returnself.emailclassUserInfo(models.Model):name=models.CharField(max_length=32)pwd=models.CharField(max_length=32)classUserToken(models.Model):token=models.CharField(max_length=64)user=models.OneToOneField(to=UserInfo)
python3 manage makemigrations
python3 manage migrate
数据库添加数据
使用postman验证:
提交登录:
使用token(已登录)查询数据信息
未登录显示:
有些健壮性判断未完成,没验证用户是否为登录状态等
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。