Django REST framework序列化方式

2022年12月6日 22:51 ry 551

作为一个Django开发前后端分离的项目者必会Django REST framework(简称drf),而在drf中序列化组件作为10个常用组件之一是肯定要掌握的,要了解序列化,我们先来看它的定义:序列化是指将对象的状态信息转换为可以存储或传输形式的过程,在django中的序列化就是将对象状态的信息转换为JSON数据,可以很方便地传递给前端。一般序列化有2种方式:1:用serializers.Serializer方式序列化,2:用serializers.ModelSerializer方式序列化。我们先来看第一种方式,这里通过drf来实现一个简单的豆瓣api应用。使用pip命令安装环境,如下所示

pip install djangorestframework==3.12.0 django-filter

我的python版本是3.7.7,django版本是2.2.4,因此去官网文档查看了对应djangorestframework对应的版本,注意确保版本不要对应不上,不然很容易报错。使用django命令创建一个django项目book,在cmd命令窗口中dos命令如图所示

C:\Users\14499\PycharmProjects>django-admin startproject book

接着pycharm中可以看到生成了一个book项目,然后使用命令创建一个app项目,先切换到book文件夹,命令如下所示,

C:\Users\14499\PycharmProjects\book>python manage.py startapp users

界面如下所示然后设计users的app的models.py,重构用户表UserProfile,这里我们使用django自带的用户表,在此基础上增加APIkey和money字段,models.py代码如下所示

from django.db import models
from django.contrib.auth.models import AbstractUser
from datetime import datetime
# Create your models here.
class UserProfile(AbstractUser):
    APIkey = models.CharField(max_length=30,verbose_name='APIkey',default='abcdefghijklmn')

    money = models.IntegerField(default=10,verbose_name='金额')
    class Meta:
        verbose_name = "用户"
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.username

在settings.py中配置用户表的继承代码,如下所示

AUTH_USER_MODEL = 'users.Userprofile'

在users的models.py新建book,整体全部代码如下

from django.db import models
from django.contrib.auth.models import AbstractUser
from datetime import datetime
# Create your models here.
class UserProfile(AbstractUser):
    APIkey = models.CharField(max_length=30,verbose_name='APIkey',default='abcdefghijklmn')

    money = models.IntegerField(default=10,verbose_name='金额')
    class Meta:
        verbose_name = "用户"
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.username
class Book(models.Model):
    title = models.CharField(max_length=30,verbose_name='书名',default='')
    isbn = models.CharField(max_length=30,verbose_name='isbn',default='')
    author = models.CharField(max_length=20,verbose_name='作者',default='')
    publish = models.CharField(max_length=30,verbose_name='出版社',default='')
    rate = models.FloatField(default=0,verbose_name='豆瓣评分')
    add_time = models.DateTimeField(default=datetime.now,verbose_name='添加时间')
    objects = models.Manager
    class Meta:
        verbose_name = "书籍信息"
        verbose_name_plural = verbose_name
    def __str__(self):
        return self.title

数据库我们使用mysql,在settings.py中设置如下代码,

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'book',
        'PORT':3306,
        'USER':'root',
        'PASSWORD':'root',
    }
}

这里book为新建的数据库名称,然后执行数据库迁移命令,如下所示

python manage.py makemigrations

python manage.py migrate

然后我们在navicat链接mysql数据库中,可以随便创建一条数据,book中表如下

Userprofile表数据如下所示

接下来正片开始了,在users目录下创建serializers.py文件,代码如下所示

from rest_framework import serializers
from .models import UserProfile,Book
from rest_framework.response import Response
from .models import UserProfile


class BookSerializer(serializers.Serializer):
    title = serializers.CharField(required=True,max_length=100)
    author = serializers.CharField(required=True,max_length=100)
    isbn = serializers.CharField(required=True,max_length=100)
    publish = serializers.CharField(required=True,max_length=100)
    rate = serializers.FloatField(default=0)

使用第一种必须根据你的models.py中的字段来序列化,我们看下views.py中代码

from django.shortcuts import render
from .serializers import BookSerializer
from rest_framework.response import Response
from rest_framework import viewsets
from rest_framework.permissions import BasePermission


from .models import Book,UserProfile
# Create your views here.
class IsDeveloper(BasePermission):
    message = "查无此人"
    def has_permission(self, request, view):
        APIKey = request.query_params.get('apikey',0)
        developer = UserProfile.objects.filter(APIkey=APIKey).first()
        if developer:
            return True
        else:
            return False
class EnoughMoney(BasePermission):
    message = "请充值"
    def has_permission(self, request, view):
        APIKey = request.query_params.get('apikey',0)
        developer = UserProfile.objects.filter(APIkey=APIKey).first()
        balance = developer.money
        if balance >0 :
            developer.money -= 1
            developer.save()
            return True
        else:
            return False
class BookModelView(viewsets.ModelViewSet):
    authentication_classes = []
    permission_classes = [IsDeveloper,EnoughMoney]
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    def get_queryset(self):
        isbn = self.request.query_params.get('isbn',0)
        books = Book.objects.filter(isbn=int(isbn))
        return books

实现功能是根据前端输入的apikey和isbn来查用户和book,没查到一个就扣一块钱,相当于豆瓣的api付费接口查询功能简化模仿版,然后在models.py同一目录下新建urls.py。里面代码如下所示

from django.urls import path
from . import views

urlpatterns = [
    path('',views.BookModelView.as_view({'get': 'list'})),
]

然后运行项目,如下所示

运行成功,然后使用第二种序列化方法,更改serilizers.py代码如下所示

from rest_framework import serializers
from .models import UserProfile,Book
from rest_framework.response import Response
from .models import UserProfile
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        #将整个字段序列化
        fields = "__all__"

再次执行,结果一样,我们发现使用第二种方式更加友好,不仅可以简化代码,还可以随意方便更改字段

如果上述代码帮助您很多,可以打赏下以减少服务器的开支吗,万分感谢!

欢迎发表评论~

点击此处登录后即可评论


评论列表
暂时还没有任何评论哦...

赣ICP备2021001574号-1

赣公网安备 36092402000079号