DRF的使用和练习记录
完成增删改查的功能.
完成认证功能.
1, 设计简单的表结构

from django.db import models __all__ = ["Book", "Publisher", "Author"] CHOICES = ( (1, "文学"), (2, "励志"), (3, "科学"), ) class Book(models.Model): title = models.CharField(verbose_name="书名", max_length=32) pub_time = models.DateField(verbose_name="出版日期") category = models.IntegerField(verbose_name="分类", choices=CHOICES) publisher = models.ForeignKey(verbose_name="出版社", to="Publisher") authors = models.ManyToManyField(verbose_name="作者", to="Author") class Meta: verbose_name = "图书信息" verbose_name_plural = "图书信息" def __str__(self): return self.title class Publisher(models.Model): title = models.CharField(verbose_name="出版社名称", max_length=32) class Meta: verbose_name_plural = verbose_name = "出版社" def __str__(self): return self.title class Author(models.Model): name = models.CharField(max_length=32, verbose_name="作者姓名") pwd = models.CharField(max_length=64, verbose_name="密码") token = models.UUIDField(null=True, blank=True)
2, admin.py中注册

from django.contrib import admin from . import models for table in models.__all__: admin.site.register(getattr(models, table))
3, 编写序列化器(app下新建一个serializers.py的文件)

from rest_framework import serializers from .models import Book class BookSerializer(serializers.Serializer): # 正序和反序列化不同的字段(仔细观察这几个字段, 选择,外键, m2m, 都是不能直接显示我们想要的字段) category_display = serializers.SerializerMethodField(read_only=True) publisher_info = serializers.SerializerMethodField(read_only=True) authors_info = serializers.SerializerMethodField(read_only=True) def get_category_display(self, obj): return obj.get_category_display() def get_publisher_info(self, obj): return {"id": obj.publisher.id, "title": obj.publisher.title} def get_authors_info(self, obj): return [{"id": author.id, "name": author.name} for author in obj.authors.all()] class Meta: model = Book fields = "__all__" # 设置默认字段的初始信息 extra_kwargs = { "category": {"write_only": True}, "publisher": {"write_only": True}, "authors": {"write_only": True}, }
4, 编写视图

import uuid from rest_framework.views import APIView from rest_framework.response import Response from .models import Book, Author from .serializers import BookSerializer from utils.authentication import MyAuth class BookView(APIView): """ 获取图书有关的信息,走的视图 """ authentication_classes = [MyAuth, ] # 注册认证信息(局部认证) def get(self, request): # 返回所有的图书信息 queryset = Book.objects.all() ser_obj = BookSerializer(queryset, many=True) return Response(ser_obj.data) def post(self, request): ser_obj = BookSerializer(data=request.data) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) class BookEditView(APIView): """ 编辑视图, 走的视图 """ def get(self, request, pk): book_obj = Book.objects.filter(id=pk).first() ser_obj = BookSerializer(book_obj) return Response(ser_obj.data) def post(self, request, pk): book_obj = Book.objects.filter(id=pk).first() ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.validated_data) else: return Response(ser_obj.errors) def delete(self, request, pk): book_obj = Book.objects.filter(id=pk) if not book_obj: return Response({"code": 1001, "error": "删除的数据不存在"}) else: book_obj.delete() return Response("") class LoginView(APIView): """ 用户登录提交表单, 将token写入数据库中 """ def post(self, request): # 获取前端传过来的用户名和密码 username = request.data.get("username", "") pwd = request.data.get("pwd", "") # 验证用户是否登录成功 user_obj = Author.objects.filter(name=username, pwd=pwd).first() if not user_obj: return Response("用户名不存在") token = uuid.uuid4() user_obj.token = token user_obj.save() # 注意保存 return Response(token)
5, 创建一个utils的文件夹, 在下面创建一个authentications.py

from rest_framework import authentication from rest_framework.exceptions import AuthenticationFailed from app01.models import Author class MyAuth(authentication.BaseAuthentication): def authenticate(self, request): token = request.query_parame.get("token", "") if not token: raise AuthenticationFailed("缺少token") # 判断token是否对应用户 user_obj = Author.objects.filter(token=token) if not user_obj: raise AuthenticationFailed("无效的token值") return user_obj, token
6, 一定要注意: 要注册rest_framework