十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
一、HyperlinkedIdentityField(用的很少)
创新互联主营宏伟网站建设的网络公司,主营网站建设方案,app软件定制开发,宏伟h5小程序设计搭建,宏伟网站营销推广欢迎宏伟等地区企业咨询
环境配置:
1、使django支持MySQL(不再介绍)
2、settings.py文件INSTALLED_APPS字段中添加"rest_framework"
urls.py
url(r'^books/', views.Books.as_view()), url(r'^publish/(?P\d+)', views.Publish.as_view(),name='ttt'),
app01/server.py
from rest_framework import serializers class AuthorSerializer(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField() class BookSerializer(serializers.Serializer): name = serializers.CharField() # publish = serializers.CharField() # 把名字换成链接地址,# view_name:路由的别名 # lookup_field:根据表指定字段,来拼路径,生成链接 # lookup_url_kwarg:默认是pk,(urls.py中的 publish/(?P\d+),指定的pk)可以不写,反向解析有名分组的名字。 publish = serializers.HyperlinkedIdentityField(view_name='ttt',lookup_field='publish_id',lookup_url_kwarg='pk')
views.py
from django.shortcuts import HttpResponse,render from rest_framework.views import APIView from django.http import JsonResponse from app01 import models from app01.server import BookSerializer # Create your views here. class Books(APIView): def get(self,request,*args,**kwargs): ret=models.Book.objects.all() book_ser=BookSerializer(ret,many=True,context={'request':request}) print(book_ser.data) return JsonResponse(book_ser.data,safe=False) class Publish(APIView): def get(self,request,*args,**kwargs): return HttpResponse('ok')
models.py
from django.db import models # Create your models here. class Book(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): return self.name class Author(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) class AuthorDatail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() addr = models.CharField(max_length=64) class Publish(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): return self.name def test(self): return self.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
-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\d+)', views.Publish.as_view(), name='ttt'),
models.py
from django.db import models # Create your models here. class Book(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): return self.name class Author(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) class AuthorDatail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() addr = models.CharField(max_length=64) class Publish(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): return self.name def test(self): return self.email
app01/server.py
from rest_framework import serializers from app01 import models class AuthorSerializer(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField() class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' authors = serializers.CharField(required=False)
views.py
from django.shortcuts import HttpResponse, render from rest_framework.views import APIView from django.http import JsonResponse from app01 import models from app01.server import BookSerializer # Create your views here. class Books(APIView): def get(self, request, *args, **kwargs): ret = models.Book.objects.all() book_ser = BookSerializer(ret, many=True, context={'request': request}) print(book_ser.data) return JsonResponse(book_ser.data, safe=False) def post(self, request, *args, **kwargs): # 前端传过来的数据从data中取 # 用序列化类的数据校验 # data参数,是要校验的数据 response = {'status': 100, 'msg': '成功'} ser = BookSerializer(data=request.data) if ser.is_valid(): # 如果数据校验通过,is_valid是True # 保存到数据库,ser是谁的对象?继承了ModelSerializer的类的对象 ser.save() else: response['status'] = 101 response['msg'] = ser.errors return JsonResponse(response, safe=False) class Publish(APIView): def get(self, request, *args, **kwargs): return HttpResponse('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位'})
from rest_framework import serializers from app01 import models class AuthorSerializer(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField() class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__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\d+)', views.BooksDetail.as_view()),
app01/server.py
from rest_framework import serializers from app01 import models class AuthorSerializer(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField() class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' name = serializers.CharField(min_length=3, error_messages={'required': '该字段必填','min_length':'最短3位'}) authors = serializers.CharField(required=False)
views.py
from django.shortcuts import HttpResponse, render from rest_framework.views import APIView from django.http import JsonResponse from app01 import models from app01.server import BookSerializer # Create your views here. class BooksDetail(APIView): def get(self, request,pk): response = {'status': 100, 'msg': '成功'} ret = models.Book.objects.all().filter(pk=pk).first() if ret: # 序列化单条,many=False book_ser = BookSerializer(ret, many=False) print(book_ser.data) response['data']=book_ser.data else: response['status']=101 response['msg']='查询不存在' return JsonResponse(response, safe=False) def put(self,request,pk): response = {'status': 100, 'msg': '成功'} ret = models.Book.objects.all().filter(pk=pk).first() if ret: # 数据校验 # 传instance和不传instance,传instance的区别 # 不传instance,调save(),往数据库新增数据 # 传instance,调save(),修改数据 ser=BookSerializer(data=request.data,instance=ret) if ser.is_valid(): ser.save() else: response['status']=101 response['msg']=ser.errors else: response['status']=102 response['msg']='修改的对象不存在' return JsonResponse(response,safe=False) class Books(APIView): def get(self, request, *args, **kwargs): ret = models.Book.objects.all() book_ser = BookSerializer(ret, many=True, context={'request': request}) print(book_ser.data) return JsonResponse(book_ser.data, safe=False) def post(self, request, *args, **kwargs): # 前端传过来的数据从data中取 # 用序列化类的数据校验 # data参数,是要校验的数据 response = {'status': 100, 'msg': '成功'} ser = BookSerializer(data=request.data) if ser.is_valid(): # 如果数据校验通过,is_valid是True # 保存到数据库,ser是谁的对象?继承了ModelSerializer的类的对象 ser.save() else: response['status'] = 101 response['msg'] = ser.errors return JsonResponse(response, safe=False) class Publish(APIView): def get(self, request, *args, **kwargs): return HttpResponse('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
from rest_framework import serializers from app01 import models from rest_framework.exceptions import ValidationError class AuthorSerializer(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField() class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' name = serializers.CharField(min_length=3, error_messages={'required': '该字段必填','min_length':'最短3位'}) authors = serializers.CharField(required=False) # 局部钩子 def validate_name(self,value): print(value) if value.startswith('sb'): raise ValidationError('不能以sb开头') else: return value
使用postman 验证
全局钩子:
app01/server.py
from rest_framework import serializers from app01 import models from rest_framework.exceptions import ValidationError class AuthorSerializer(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField() class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' name = serializers.CharField(min_length=3, error_messages={'required': '该字段必填','min_length':'最短3位'}) authors = serializers.CharField(required=False) # 全局钩子 # value是所有效验通过数据的字典 def validate(self, value): name=value.get('name') price=value.get('price') if name and price: if str(name)==str(price): return value else: raise ValidationError('名字跟价格不相等') return value
使用postman验证:
五、认证组件初始
urls.py
url(r'^books/$', views.Books.as_view()), url(r'^books/(?P\d+)', views.BooksDetail.as_view()), url(r'^publish/(?P \d+)', views.Publish.as_view(), name='ttt'), url(r'^login/', views.login.as_view()),
app01/server.py (与之前一样,没改过)
from rest_framework import serializers from app01 import models from rest_framework.exceptions import ValidationError class AuthorSerializer(serializers.Serializer): nid = serializers.CharField() name = serializers.CharField() age = serializers.CharField() class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' name = serializers.CharField(min_length=3, error_messages={'required': '该字段必填','min_length':'最短3位'}) authors = serializers.CharField(required=False) # 局部钩子 def validate_name(self,value): print(value) if value.startswith('sb'): raise ValidationError('不能以sb开头') else: return value # 全局钩子 # value是所有效验通过数据的字典 def validate(self, value): name=value.get('name') price=value.get('price') if name and price: if str(name)==str(price): return value else: raise ValidationError('名字跟价格不相等') return value
views.py
from django.shortcuts import HttpResponse, render from rest_framework.views import APIView from django.http import JsonResponse from app01 import models from app01.server import BookSerializer # Create your views here. from rest_framework import exceptions class Auth(): def authenticate(self, request): # 请求来的东西都能拿出来 # 包装后的request对象,请求来的所有东西都能拿出来 # 如果认证通过,需要返回东西,如果认证不通过,要抛异常 token = request.GET.get('token') ret = models.UserToken.objects.filter(token=token).first() # 如果有值,说明登录过了,而且带的随机字符串也是正确的 if ret: return None else: # 如果没有值,抛异常 raise exceptions.APIException('请登录') from rest_framework.request import Request class BooksDetail(APIView): authentication_classes = [Auth] def get(self, request, pk): response = {'status': 100, 'msg': '成功'} ret = models.Book.objects.all().filter(pk=pk).first() if ret: # 序列化单条,many=False book_ser = BookSerializer(ret, many=False) print(book_ser.data) response['data'] = book_ser.data else: response['status'] = 101 response['msg'] = '查询不存在' return JsonResponse(response, safe=False) def put(self, request, pk): response = {'status': 100, 'msg': '成功'} ret = models.Book.objects.all().filter(pk=pk).first() if ret: # 数据校验 # 传instance和不传instance,传instance的区别 # 不传instance,调save(),往数据库新增数据 # 传instance,调save(),修改数据 ser = BookSerializer(data=request.data, instance=ret) if ser.is_valid(): ser.save() else: response['status'] = 101 response['msg'] = ser.errors else: response['status'] = 102 response['msg'] = '修改的对象不存在' return JsonResponse(response, safe=False) class Books(APIView): def get(self, request, *args, **kwargs): ret = models.Book.objects.all() book_ser = BookSerializer(ret, many=True, context={'request': request}) print(book_ser.data) return JsonResponse(book_ser.data, safe=False) def post(self, request, *args, **kwargs): # 前端传过来的数据从data中取 # 用序列化类的数据校验 # data参数,是要校验的数据 response = {'status': 100, 'msg': '成功'} ser = BookSerializer(data=request.data) if ser.is_valid(): # 如果数据校验通过,is_valid是True # 保存到数据库,ser是谁的对象?继承了ModelSerializer的类的对象 ser.save() else: response['status'] = 101 response['msg'] = ser.errors return JsonResponse(response, safe=False) class Publish(APIView): def get(self, request, *args, **kwargs): return HttpResponse('ok') import uuid class login(APIView): def post(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() if not user: response['status'] = 101 response['msg'] = '用户名密码错误' else: # 生成一个随机字符串 token = uuid.uuid4() # 去数据库保存 models.UserToken.objects.create(token=token, user=user) response['token'] = token return JsonResponse(response, safe=False)
models.py
from django.db import models # Create your models here. class Book(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): return self.name class Author(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) class AuthorDatail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() addr = models.CharField(max_length=64) class Publish(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): return self.name def test(self): return self.email class UserInfo(models.Model): name = models.CharField(max_length=32) pwd = models.CharField(max_length=32) class UserToken(models.Model): token = models.CharField(max_length=64) user = models.OneToOneField(to=UserInfo)
python3 manage makemigrations
python3 manage migrate
数据库添加数据
使用postman 验证:
提交登录:
使用token(已登录)查询数据信息
未登录显示:
有些健壮性判断未完成,没验证用户是否为登录状态等