初级
#models.py from django.db import models class User(models.Model): user = models.CharField(max_length=32) password = models.CharField(max_length=32) user_detail = models.OneToOneField(to='UserDetail', on_delete=models.SET_NULL, null=True, db_constraint=False) def account_msg(self): return self.user + ":" + self.password class UserDetail(models.Model): phone_num = models.CharField(max_length=11) info = models.TextField() # 自定义序列化类:为具体的类提供序列化 # objectjson.py from rest_framework import serializers class UserJson(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField(source='user') password = serializers.CharField() account = serializers.CharField(source='account_msg') # user_detail = serializers.CharField() # user_phone_num = serializers.CharField(source='user_detail.phone_num') detail = serializers.SerializerMethodField() def get_detail(self, object): return {'phone': object.user_detail.phone_num, 'info': object.user_detail.info}#自定义返回的数据格式 #views.py from rest_framework.views import APIView from rest_framework.response import Response from app import objectjson, models class Users(APIView): def get(self, request): user_list = models.User.objects.all() user_data = objectjson.UserJson(user_list, many=True).data return Response({ 'status': 0, 'message': 'ok', 'results': user_data }) #urls.py urlpatterns = [ url(r'^users/', views.Users.as_view()), ]
高级
#models.py class Book(models.Model): name = models.CharField(max_length=20) price = models.DecimalField(max_digits=5, decimal_places=2) author = models.ManyToManyField('Author', db_constraint=False) class Author(models.Model): name = models.CharField(max_length=20) author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.SET_NULL, null=True, db_constraint=False) class AuthorDetail(models.Model): age = models.IntegerField() telephone = models.BigIntegerField() # 自定义序列化类:为具体的类提供序列化 # objectjson.py class AuthorDetailJson(serializers.ModelSerializer): class Meta: model = models.AuthorDetail # fields ='__all__' #对外提供所有字段 exclude = ['id'] # 和fields两者取一,代表除id字段不提供 class AuthorJson(serializers.ModelSerializer): class Meta: model = models.Author fields = ['id', 'name', 'detail'] # 自定义的detail字段也要声明也要提供哪些字段 # fields = '__all__' detail = serializers.SerializerMethodField() # exclude = ['author_detail'] def get_detail(self, object): detail_data = AuthorDetailJson(object.author_detail).data return detail_data class BookJson(serializers.ModelSerializer): class Meta: model = models.Book exclude = ['author'] # fields = '__all__' # depth = 2 authors = serializers.SerializerMethodField() def get_authors(self, object): author_list = object.author.all() author_data = AuthorJson(author_list, many=True).data return author_data #views.py class Books(APIView): def get(self, request): book_list = models.Book.objects.all() book_data = objectjson.BookJson(book_list, many=True).data return Response({ 'status': 0, 'message': 'ok', 'results': book_data }) #urls.py urlpatterns = [ url(r'^books/', views.Books.as_view()), ]
校验
# objectjson.py class BookJson(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' #单个字段校验 name = serializers.CharField(min_length=3, max_length=5, error_messages= { 'min_length': '太短了', 'max_length': '太长了' }) # 局部钩子 def validate_name(self, value): from rest_framework.exceptions import ValidationError book_object = models.Book.objects.filter(name=value) if book_object: raise ValidationError('书名已经存在') if 'sb' in value: raise ValidationError('不能出现敏感词汇') return value # views.py class Books(APIView): def post(self, request): book = request.data book_json = objectjson.BookJson(data=book) # 必须明确data if book_json.is_valid(): book_json.save() return Response({ 'status': 0, 'message': 'ok', 'results': book_json.data }) return Response({ 'status': 1, 'msg': book_json.errors })
全局钩子
# 全局钩子校验 def validate(self, attrs): from rest_framework.exceptions import ValidationError pwd = attrs.get('pwd') re_pwd = attrs.get('re_pwd') if pwd == re_pwd: return attrs else: raise ValidationError('密码校验失败')
数据删改查
# views.py class Book(APIView): def get(self, request, id): book = models.Book.objects.filter(pk=id).first() book_data = objson.BookJson(book).data return Response({ 'status': 0, 'msg': 'ok', 'results': book_data }) def put(self, request, id): book = models.Book.objects.filter(pk=id).first() book_json = objson.BookJson(data=request.data, instance=book) # 通过instance标识修改的对象 if book_json.is_valid(): book_json.save() # 同样用save更新到数据库 return Response({ 'status': 0, 'msg': 'ok', 'results': book_json.data }) return Response({ 'status': 1, 'msg': book_json.errors, }) def delete(self,request,id): models.Book.objects.filter(pk=id).delete() # 删除操作直接用ORM操作数据库 return Response({ 'status': 2, 'msg': 'delete success', })
基于ORM操作增删改
class Books(APIView): #获取所有书籍 def get(self, request): book_list = models.Book.objects.all() book_data = objectjson.BookJson(book_list, many=True).data return Response({ 'status': 0, 'message': 'ok', 'results': book_data }) #增加书籍 def post(self, request): name = request.data.get('name') price = request.data.get('price') author = request.data.get('author') book_object = models.Book.objects.create(name=name, price=price) book_object.author.add(*author) book_data = objectjson.BookJson(book_object).data return Response({ 'status': 0, 'message': 'ok', 'results': book_data }) class Book(APIView): #获取一本书籍 def get(self, request, id): book = models.Book.objects.filter(pk=id).first() book_data = objectjson.BookJson(book).data return Response({ 'status': 0, 'message': 'ok', 'results': book_data }) #修改书籍 def put(self, request, id): book_object = models.Book.objects.filter(pk=id).first() # type:models.Book name = request.data.get('name') price = request.data.get('price') author = request.data.get('author') book_object.name = name book_object.price = price book_object.author = author book_object.save() book_data = objectjson.BookJson(book_object).data return Response({ 'status': 0, 'message': 'ok', 'results': book_data }) #删除书籍 def delete(self, request, id): models.Book.objects.filter(pk=id).delete() return Response({ 'status': 0, 'message': 'ok', 'results': 'delete success' })
Django跨域问题
什么是跨域
''' 通常情况下,A网站访问B服务器资源时,不满足以下三个条件其一就是跨域访问 1.协议不同 2.端口不同 3.主机不同 '''
Django解决跨域
''' 安装django-cors-headers模块 在settings.py中配置 # 注册app INSTALLED_APPS =[ ... 'corsheaders' ] #添加中间件 MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware' ] #允许跨域源 CORS_ORIGIN_ALLOW_ALL = True '''
# views.py class Auth: def authenticate(self,request): #完全具备认证功能 pass class Book(APIView): authentication_classes = [Auth,]
认证源码流程
""" 1.views.Books.as_view()2.view = super(APIView, cls).as_view(**initkwargs) 分发给dispatch 3.def dispatch(self, request, *args, **kwargs): 4. request = self.initialize_request(request, *args, **kwargs) 封装request self.initial(request, *args, **kwargs) 三大认证 5.self.perform_authentication(request) 转向Request类的user 6.request.py的Request的user self._authenticate() 7.self.authenticators self是drf的request对象 8.drf的request对象的init方法 authenticators是初始化参数 9.在哪初始化的: request = def initialize_request(self, request, *args, **kwargs) 10.self.get_authenticators() 需要 self.authentication_classes 11.self代表APIView类或子类对象,在自定义Books(APIView)中提供 """