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)
表结构设计(models.py)

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

posted @ 2018-11-08 20:05  猴里吧唧  阅读(110)  评论(0)    收藏  举报