一、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(已登录)查询数据信息

未登录显示:

有些健壮性判断未完成,没验证用户是否为登录状态等