1 自定义user表,签发token,认证类
表模型
class MyUser(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=32) phone = models.CharField(max_length=32) email = models.EmailField()
路由
path('login2/', views.MyLoginView.as_view()),
视图
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER from rest_framework_jwt.views import obtain_jwt_token class MyLoginView(APIView): def post(self, request, *args, **kwargs): username = request.data.get('username') password = request.data.get('password') # 如果是手机号 if re.match('^1[3-9]\d{9}$', username): # 以手机号登录 user = MyUser.objects.filter(phone=username).first() elif re.match('^.+@.+$', username): # 以邮箱登录 user = MyUser.objects.filter(email=username).first() else: # 以用户名登录 user = MyUser.objects.filter(username=username).first() # 如果user有值并且密码正确 if user and user.password == password: # 登录成功,生成token # drf-jwt中有通过user对象生成token的方法 payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return APIResponse(token=token, username=user.username) else: return APIResponse(code=101, msg='用户名或密码错误')
2 book,publish,author表关系及抽象表建立
# 注意:以后所有的数据删除,尽量用软删除,使用一个字段标志是否删除,而不是真正的从数据库中删除 -好处:1 这样删除数据不会影响索引,不会导致索引失效 2 之前存的用户数据还在,以备以后使用 # 表模型如下 # 抽象出一个基表(不再数据库生成,abstract=True),只用来继承 class BaseModel(models.Model): is_delete = models.BooleanField(default=False) create_time = models.DateTimeField(auto_now_add=True) class Meta: # 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表 abstract = True class Book(BaseModel): name = models.CharField(max_length=16) price = models.DecimalField(max_digits=5, decimal_places=2) publish = models.ForeignKey(to='Publish', db_constraint=False, on_delete=models.DO_NOTHING) # 重点:多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联 # ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义关系表 authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False) @property def publish_name(self): return self.publish.name @property def author_list(self): # ll=[] # for author in self.authors.all(): # ll.append({'name':author.name,'sex':author.get_sex_display()}) return [{'name': author.name, 'sex': author.get_sex_display()} for author in self.authors.all()] class Publish(BaseModel): name = models.CharField(max_length=16) address = models.CharField(max_length=64) class Author(BaseModel): name = models.CharField(max_length=16) sex = models.IntegerField(choices=[(0, '男'), (1, '女')], default=0) class AuthorDetail(BaseModel): mobile = models.CharField(max_length=11) # 有作者可以没有详情,删除作者,详情一定会被级联删除 # 外键字段为正向查询字段,related_name是反向查询字段 author = models.OneToOneField(to='Author', related_name='detail', db_constraint=False, on_delete=models.CASCADE)
3 book表单增群增
class BookView(APIView): def post(self, request, *args, **kwargs): if isinstance(request.data, dict): # 增一条 ser = serializer.BookSerializer(data=request.data) ser.is_valid(raise_exception=True) ser.save() return APIResponse(data=ser.data) elif isinstance(request.data, list): # 增多条 ser = serializer.BookSerializer(data=request.data, many=True) # 内部如何实现的? # many=True,ser不是BookSerializer对象,而是ListSerializer对象,套了一个个的BookSerializer print(type(ser)) ser.is_valid(raise_exception=True) # from rest_framework.serializers import ListSerializer ser.save() # ListSerializer的save return APIResponse(msg='增加%s条成功' % len(request.data))
4 book表单查群查
class BookView(APIView): def get(self, request, *args, **kwargs): pk = kwargs.get('pk', None) if pk: # 单查 # 方式一 # book=models.Book.objects.filter(id=pk).filter(is_delete=False).first() # if not book: # raise Exception('要查询的不存在') # 方式二 book = models.Book.objects.get(id=pk, is_delete=False) ser = serializer.BookSerializer(instance=book) else: # 查所有 book_list = models.Book.objects.all().filter(is_delete=False) ser = serializer.BookSerializer(instance=book_list, many=True) return APIResponse(data=ser.data)
5 book表单改群改
class BookView(APIView): def put(self, request, *args, **kwargs): pk = kwargs.get('pk', None) if pk: # 单条修改 book = models.Book.objects.get(id=pk, is_delete=False) ser = serializer.BookSerializer(instance=book, data=request.data) ser.is_valid(raise_exception=True) ser.save() return APIResponse(msg='修改成功') else: # 分析:ListSerializer的update方法没有写,需要我们自己写 from rest_framework.serializers import ListSerializer # pks=[item['id'] for item in request.data] # 如果不重写ListSerializer的update方法,这是存不进去的 pks = [] for item in request.data: pks.append(item['id']) item.pop('id') print(request.data) book_list = models.Book.objects.filter(id__in=pks, is_delete=False) ser = serializer.BookSerializer(instance=book_list, data=request.data, many=True) print(type(ser)) ser.is_valid(raise_exception=True) ser.save() return APIResponse(msg='修改%s条成功') # 你们能想到的方法 # pks = [] # for item in request.data: # pks.append(item['id']) # item.pop('id') # book_list = models.Book.objects.filter(id__in=pks, is_delete=False) # # for i,book in enumerate(book_list): # ser = serializer.BookSerializer(instance=book, data=request.data[i]) # ser.is_valid(raise_exception=True) # ser.save() # return APIResponse(msg='修改%s条成功'%len(book_list))
6 book表的单删群删
class BookView(APIView): def delete(self, request, *args, **kwargs): pk = kwargs.get('pk', None) pks = [] if pk: # 单条删除 # res=models.Book.objects.filter(id=pk).update(is_delete=True) # print(res) # return APIResponse(msg='删除成功') pks.append(pk) else: pks = request.data res = models.Book.objects.filter(id__in=pks).update(is_delete=True) if res >= 1: return APIResponse(msg='删除%s条成功' % res) else: # raise Exception('没有要删除的数据') return APIResponse(code=999, msg='没有要删除的数据')
7 序列化类
from app01 import models class ListBookSerializer(serializers.ListSerializer): # def create(self, validated_data): # print('=======',validated_data) # return '1' def update(self, instance, validated_data): print(instance) # book_list:是一堆图书对象 print(validated_data) # 列表套字典,是要修改的数据 return [self.child.update(book, validated_data[i]) for i, book in enumerate(instance)] class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book list_serializer_class=ListBookSerializer # 指定many=True的时候,生成的ListBookSerializer的对象了 fields = ['name', 'price', 'publish', 'authors', 'publish_name', 'author_list'] extra_kwargs = { 'publish': {'write_only': True}, 'authors': {'write_only': True}, 'publish_name': {'read_only': True}, 'author_list': {'read_only': True}, } # def create(self, validated_data): # print(validated_data)
路由
path('books/', views.BookView.as_view()), re_path('books/(?P<pk>\d+)', views.BookView.as_view()),
1 自定义token的签发和认证:https://www.cnblogs.com/liuqingzheng/articles/9766397.html