django的DRF(三)

这篇具有很好参考价值的文章主要介绍了django的DRF(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、基本概念

DRF(Django Rest Framework)是可以快速基于Restful开发得Django应用得插件,功能非常多,被广泛应用。
所谓Restful风格就是不在用户请求的URL当中说明 “操作动作(create,delete,put)”。而是直接请求资源,通过不同的http方法来做对应的操作。
比如:

GET 127.0.0.1:8000/app1/   获取app1应用的所有资源
POST 127.0.0.1:8000/app1/  新增app1响应的数据

GET 127.0.0.1:8000/app1/1     获取app1应用下主键为 1 的资源
PUT 127.0.0.1:8000/app1/1     修改app1应用下主键为 1 的资源
delete 127.0.0.1:8000/app1/1  删除app1应用下主键为 1 的资源

二、安装

pip install djangorestframework

注册:
在settings.py文件中进行注册.注册之后呢,在使用浏览器访问的时候,返回的结果会渲染成html页面

INSTALLED_APPS = [
	......
    'rest_framework',
]

三、DRF的视图类

django的视图类: View
DRF的视图类: APIView
View是APIView的父类,所以这两个视图类的用法是一样的

1.APIView

1.1 创建应用

django-admin startapp app1

1.2 配置总路由

编辑项目目录下的总urls.py文件

urlpatterns = [
    path('app1/',include('app1.urls')),
]

1.3 新建分布式路文件

在app1应用目录下新建urls.py文件,内容如下

from django.urls import  path
from .views import *

urlpatterns = [
    path('',test.as_view()),
]

1.4 新建视图函数

from rest_framework.views import  APIView,Response

class test(APIView):
    def get(self,request):
        return  Response({"message": "访问GET方法成功"})

    def post(self,request):
        return  Response({"message": "访问POST方法成功"})

1.5 验证

分别使用GET方法和POST方法请求以下连接

http://127.0.0.1:8000/app1/

2.APIView GET请求

request.query_params: 获取GET请求所有参数
request.query_params.get("name") :获取get请求中某个key的值

视图函数:

from rest_framework.views import  APIView,Response

class test(APIView):
    def get(self,request):
        print(request.query_params)
        print(request.query_params.get("name"))
        return  Response({"message": "访问GET方法成功"})

发送请求验证

http://127.0.0.1:8000/app1/?name=zhangsan&password=123 

结果如下:

<QueryDict: {'name': ['zhangsan'], 'password': ['123']}> 
zhangsan 

3.APIView POST请求

request.data.get() : 获取post请求的数据

视图函数如下:

from rest_framework.views import  APIView,Response

class test(APIView):
    def post(self,request):
        print(f'POST的数据 = {request.data.get("user")}')
        print(f'POST的数据 = {request.data.get("password")}')
        return  Response({"message": "访问POST方法成功"})

发送POST请求

http://127.0.0.1:8000/app1/

form-data 如下:
user:admin
password: 123123

结果如下:

POST的数据 = admin 
POST的数据 = 123123 

4.DRF的Response

DRF封装了自己的Response,对django的Httpsponse进行了封装和增强,可以直接对字典进行序列化。代码如下:

from rest_framework.response import Response
data = {
    "usernmae": "张三",
    "age": 100
}


class test(APIView):
    def get(self,request):
        return  Response(data)


使用get请求访问

http://127.0.0.1:8000/app1/

返回结果如下:

{
    "usernmae": "张三",
    "age": 100
}

四、DRF序列化

1.概念

1.1 序列化

将内存中对象存储下来,把它变成一个个字节。
简单来讲: 数据结构–>二进制
举例:python中的json.dumps()就是序列化函数。将python中的字典转换成json格式的字符串的过程就是序列化

1.2.反序列化

将文件得一个个字节恢复成内存中得对象
简单来讲: 二进制–>数据结构
举例:python中的json.loads()就是反序列化,将json字符串转换成python的中字典的过程称为反序列化。

1.3 DRF序列化

在DRF中:model类–>字典–>JSON字符串(字符序列)
django中得DRF主要是配置model类来使用得。他主要是将"model类得实例" 转化为 “字典”。再由json模块转换为json字符串.

1.4 DRF反序列化

在DRF中:JSON字符串–>字典–>model类(入库持久化)
浏览器提交过来得数据,DRF做数据校验,在入库

2.序列化器

1.创建数据库model类

!!! 注意 !!!:这里定义模型类的时候,不要定义id字段,django在迁移的时候,会自动生成id字段,并且是primary_key 和自增长的字段。
如果写了,在后边写PUT方法的时候,会有一个报错:如果POST的数据中不传递id 会报错,说ID是必填字段。如果填写了又说ID是存在的。

在应用app1的models.py中编写mode类

from django.db import models

class student(models.Model):
    class Meta:
        db_table = 'my_student'
        
    name = models.CharField(max_length=20)
    age = models.IntegerField()

进行迁移

python manage.py makemigrations
python manage.py migrate

查看生成的表结构

mysql> desc my_student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| name  | varchar(20) | NO   |     | NULL    |                |
| age   | int(11)     | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

2.插入内容

INSERT INTO my_student VALUES (0,'zhangsan',20),(0,'lisi',21),(0,'wangwu',20),(0,'xiaoqiang',26),(0,'xiaoming',22);

mysql> select * from my_student;
+----+-----------+-----+
| id | name      | age |
+----+-----------+-----+
|  1 | zhangsan  |  20 |
|  2 | lisi      |  21 |
|  3 | wangwu    |  20 |
|  4 | xiaoqiang |  26 |
|  5 | xiaoming  |  22 |
+----+-----------+-----+
5 rows in set (0.00 sec

3.创建序列化器

在app1的应用目录下创建serializers.py文件.文件名是可以自定义的。
DRF提供了一个类:serializers.ModelSerializer。这个类就帮我们做了序列化器和model字段的一一对应
这一步创建序列化器才是在序列化过程中最重要的的步骤。

from .models import *
from rest_framework import serializers

class student_serializers(serializers.ModelSerializer):
    class Meta:
        # 这是对student 类进行序列化
        model = student
        # 序列化所有字段
        fields = '__all__'

3.序列化

注意:单行序列化 获取数据库数据时使用的是objects.get()
多行序列化 获取数据库数据时使用的是objects.filter(),并且做数据转换的时候必须使用many=True参数。

编写路由

编辑app1应用下的路由文件urls.py。
这里使用了两个函数test和testDetail

from django.urls import  path
from .views import *

urlpatterns = [
	# 这个路由是为了符合restful风格的接口,get所有资源准备的路由.
    path('',test.as_view()),
    
    # 这个路由是为了对单个资源进行操作的路由.
	# 在路由中也定义了 用来定位资源的变量: id
    path('<int:id>/',testDetail.as_view())
]

1 单行序列化

编写app1应用下视图函数文件views.py

from rest_framework.views import  APIView,Response
from .models import *
from .serializers import *

class testDetail(APIView):
    def get(self, request,id):
        # 获取单行数据库数据
        res = student.objects.get(pk=id)

        # 使用自定义序列化器 对结果进行序列化,并且使用.data返回序列化后的数据
        ser_data = student_serializers(instance=res).data

        # 将最后的结果序列化为json返回给用户
        return Response(ser_data)

用户使用GET请求

http://127.0.0.1:8000/app1/2

结果如下:

{
    "id": 2,
    "name": "lisi",
    "age": 21
}

2 多行序列化

依然是app1下视图函数文件views.py文件

from rest_framework.views import  APIView,Response
from .models import *
from .serializers import *

# 这个函数和上边不是一个函数
class test(APIView):
    def get(self,request):
        # 获取数据库 符合条件的多行数据集。这里的参数应该是用户传递过来的,这里就直接写了
        res = student.objects.filter(age__gt=20)
        
        # 对多行数据集合进行序列化
        ser_data = student_serializers(instance=res,many=True).data
        
        # 将数据序列化后返回给用户
        return  Response(ser_data)

结果如下:

[
    {
        "id": 2,
        "name": "lisi",
        "age": 21
    },
    {
        "id": 4,
        "name": "xiaoqiang",
        "age": 26
    },
    {
        "id": 5,
        "name": "xiaoming",
        "age": 22
    }
]

4、反序列化

1.新增数据(POST)

视图函数如下:

from rest_framework.views import  APIView,Response
from .models import *
from .serializers import *

class test(APIView):
	def get()
        ......
    
    # 新增POST方法
    def post(self,request):
        # 将用户post的请求的数据传递给序列化器
        ser_data = student_serializers(data=request.data)

        # 序列化器对 用户提交的数据进行合法校验
        if ser_data.is_valid():
            ser_data.save()
            return  Response("数据写入成功")


用户访问路由,使用POST方法:

http://127.0.0.1:8000/app1/

用户POST数据为:
{
    "name": "zhangwuji",
    "age": 20
}

查看数据库,数据已经添加成功

mysql> select * from my_student;
+----+-----------+-----+
| id | name      | age |
+----+-----------+-----+
|  1 | zhangsan  |  20 |
|  2 | lisi      |  21 |
|  3 | wangwu    |  20 |
|  4 | xiaoqiang |  26 |
|  5 | xiaoming  |  22 |
|  6 | zhangwuji |  20 |
+----+-----------+-----+
6 rows in set (0.00 sec)

2.更新数据(PUT)

class testDetail(APIView):
    def get(self,request,id):
        pass
    
    # 新增put方法
    def put(self,request,id):
        query_data = student.objects.get(pk=id)
        ser_save_data = student_serializers(instance=query_data, data=request.data)
        if ser_save_data.is_valid():
            ser_save_data.save()
            return  Response("数据修改成功")
        else:
            print(ser_save_data.errors)
            return  Response("数据修改失败")

使用PUT方法访问:

PUT   http://127.0.0.1:8000/app1/6/

将zhangwuji改为zhangsanfeng,提交数据为:

{
    "name": "zhangsanfeng",
    "age": 20
}

查看结果修改成功

mysql> select * from my_student;
+----+--------------+-----+
| id | name         | age |
+----+--------------+-----+
|  1 | zhangsan     |  20 |
|  2 | lisi         |  21 |
|  3 | wangwu       |  20 |
|  4 | xiaoqiang    |  26 |
|  5 | xiaoming     |  22 |
|  6 | zhangsanfeng |  20 |
+----+--------------+-----+
6 rows in set (0.00 sec)

3.删除数据

class testDetail(APIView):
    def get(self,request,id):
        pass
    def put(self,request,id):
    	pass
    
    # 新增delete方法
	def delete(self,request,id):
        try:
            query_data = student.objects.get(pk=id)
            query_data.delete()
        except Exception:
            return Response("数据删除失败")
        else:
            return Response("数据删除成功")

使用delete方法请求.无需post数据。
删除id为 6 的数据

http://127.0.0.1:8000/app1/6/

5.总结

这里一共两个函数,5个方法。增删改查查


class test(APIView):
	# 获取所有资源
	def get()
	
	# 添加一个资源
	def post()
	
class testDetail(APIView):
	# 获取单个资源
	def get()
	
	# 修改单个资源
	def put()
	
	#删除单个资源
	def delete()

如下图:

五、通用视图类

1.视图类的缺点

使用了APIview确实有些了增强的部分,但是如果有多个应用,或者一个应用里多个业务类,那就会有很多的重复代码。
重复代码指的是:
1.每一个业务类当中都要重复写get、post方法
2.每一个方法当中都要重复写 查询集合,序列化器、数据校验、数据保存等
于是:DRF又提供了genericAPIview和mixins

2.GenericAPIView

GenericAPIView主要是提供了两个变量,这两个变量的名称是固定写法。因为源码里是这么写的。这两个变量主要是提供给Mixins类使用的。

from rest_framework.generics import GenericAPIView

1.queryset: 得出查询数据库数据的集合
2.serializer_class:  指定序列化器

3.mixins类

在View和APIView中,我们都需要手写了get、put、post等方法,来处理增删改查查的数据。
DRF中提供了这5个类,和get、put、delete、get、post的功能一样,而且比自己写的处理数据逻辑更严谨

ListModelMixin: 查所有
RetrieveModelMixin:查单条

CreateModelMixin:新增
UpdateModelMixin:更新
DestroyModelMixin:删除

4.组合使用

4.1 总路由

urlpatterns = [
    path('app1/',include('app1.urls')),
]

4.2 子路由

from django.urls import  path
from .views import *

urlpatterns = [
    path('',test.as_view()),
    
    # 这里的变量名必须叫做pk. 前边的视图函数可以自定义,参数也可以自定义,所以这里的路由变量也可以自定义。
	# 但是现在用的是GenericAPIView类,源码当中定义的叫做pk,所以这里必须叫做pk
    path('<int:pk>',testDetail.as_view())
]

4.3 model类和序列化器

model类和序列化器没有变化,依然使用上边"四"中的配置即可

4.4 视图函数

编辑views.py文件

from rest_framework.generics import GenericAPIView
from rest_framework.mixins import (
    ListModelMixin,RetrieveModelMixin,
    CreateModelMixin,UpdateModelMixin,DestroyModelMixin
)
from .models import *
from .serializers import *


class test(GenericAPIView,ListModelMixin,CreateModelMixin):
    queryset = student.objects.all()
    serializer_class = student_serializers

    # 这里之所以要这样赋值,根本原因是APIView和View都是通过dispatch方法,根据方法的名称进行的请求分发。
    # 所以DRF提供的5个处理数据的方法,最终名称还是要和put、post等5个方法的名称对应上。否则dispatch方法无法找到视图类
    get = ListModelMixin.list
    post = CreateModelMixin.create

class testDetail(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
    queryset = student.objects.all()
    serializer_class = student_serializers

    get = RetrieveModelMixin.retrieve
    put = UpdateModelMixin.update
    delete = DestroyModelMixin.destroy

4.5 测试

DRF默认不支持批量新增和批量修改

1.get所有资源   http://127.0.0.1:8000/app1/
2.get单个资源   http://127.0.0.1:8000/app1/2
3.delete单个数据  http://127.0.0.1:8000/app1/9

4.post单个数据   http://127.0.0.1:8000/app1/    
 数据如下:
{
    "name": "zhangsanfeng",
    "age": 20
}

5.put 单个数据   http://127.0.0.1:8000/app1/2
数据如下:
{
    "name": "xiaoli",
    "age": 25
}

六、concreteAPIView(混凝土)

在 五 中我们需要手动继承和组合genenicAPIView和mixins类。genenicAPIView和minxinx提供的功能类进行自由组合。这样继承的类相对来说较多。
因此DRF又提供了写好的genicAPIview和mixIn的组合类。如果不需要自定义的化,可以使用提前定义好的view类

1.组合方式

concreteAPIview 组合方式 方法 功能
CreateAPIView GenericAPIView, CreateModelMixin post 列表页新增对象功能
ListAPIView GenericAPIView, ListModelMixin get 获得列表页内容
ListCreateAPIView GenericAPIView, ListModelMixin, CreateModelMixin post,get 完整的列表页功能
RetrieveAPIView GenericAPIView, RetrieveModelMixin get 获取单个对象
UpdateAPIView GenericAPIView, UpdateModelMixin put、 patch 修改单个对象
DestroyAPIView GenericAPIView, DestroyModelMixin delete 删除单个对象
RetrieveUpdateDestroyAPIView GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin get、 put、 patch、 delete 完整的详情页查、 改、删 功能

2.路由

总路由和子路由配置不变。和五中的配置保持一致

3.视图使用

视图函数如下:这里需要指定queryset和序列化器类就可以了。
优点:
1.继承的类更加简洁明了
2.不用再写get、post、put、delete等所有方法了。

from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView
from .models import *
from .serializers import *

class test(ListCreateAPIView):
    queryset = student.objects.all()
    serializer_class = student_serializers


class testDetail(RetrieveUpdateDestroyAPIView):
    queryset = student.objects.all()
    serializer_class = student_serializers

七、路由Router与视图集ViewSets

concreteAPIView视图类已经非常简练了,已经不用再写操作数据库的逻辑代码。只需要指定数据集合和序列化器类就可以了。
但是目前的状况还是有一点问题:
1.路由要写两条。一条是列表页路由,一条是详情页路由
2.视图函数也是两个,一个是列表页处理函数,一个是详情页处理函数。并且要重复指定queryset和serializer_class

DRF中的router解决了问题1
DRF中的ViewSets解决了问题2

1.配置总路由

编辑urls.py

from django.urls import path,include

urlpatterns = [
    path('app1/',include('app1.urls')),

]

2.配置子路由

编辑app1下的urls.py文件

from django.urls import  path
from .views import *
from rest_framework.routers import SimpleRouter


urlpatterns = [

]


router = SimpleRouter()
router.register('db',test)

# 查看生成了哪些路由条目
for url in router.urls:
    print(f'url = {url}')

urlpatterns += router.urls

在启动项目的时候在日志中可以看到生成了两条路由

# 这个对应列表页路由
url = <URLPattern '^db/$' [name='student-list']> 
    
# 这个对应详情页路由
url = <URLPattern '^db/(?P<pk>[^/.]+)/$' [name='student-detail']> 

3.配置视图集

这里的视图类也不在用写两个了,写一个就可以了

from rest_framework.viewsets import ModelViewSet
from .models import *
from .serializers import *

class test(ModelViewSet):
    queryset = student.objects.all()
    serializer_class = student_serializers

测试增删改查查文章来源地址https://www.toymoban.com/news/detail-832984.html

到了这里,关于django的DRF(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【python】web应用开发DRF框架

    【python】web应用开发DRF框架 Django rest_framework, 简称 drf, 可以更方便的使用django写出符合 RESTful 规范的接口, (缩减编写api接口的代码) Django REST framework是一个建立在Django基础之上的Web应用开发框架(Django的一个app),可以快速的开发REST API接口应用 在REST framework中,提供了序列化器

    2024年02月11日
    浏览(56)
  • 二挡起步——pythonweb开发Django框架,前端原生+Django后端框架002(附带小案例)

     大家好,我是csdn的博主: lqj_本人 这是我的个人博客主页: lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主 lqj_本人擅长微信小程序,前端,python,等方面的知识 https://blog.csdn.net/lbcyllqj?spm=1011.2415.3001.5343 哔哩哔哩欢迎关注: 小淼Develop 小淼Develop的个人空间-小淼Develop个

    2024年02月03日
    浏览(72)
  • Django进阶:DRF(Django REST framework)

    DRF 即 Django REST framework 的缩写,官网上说: Django REST framework 是一个强大而灵活的工具包,用于 构建Web API 。 简单来说:通过DRF创建API后,就可以通过HTTP请求来获取、创建、更新或删除数据(CRUD)。 那么为什么要构建API呢? 在Django中,我们通过 model-view-template 实现了 后端和前

    2024年02月11日
    浏览(38)
  • django的DRF(三)

    DRF(Django Rest Framework)是可以快速基于Restful开发得Django应用得插件,功能非常多,被广泛应用。 所谓Restful风格就是不在用户请求的URL当中说明 “操作动作(create,delete,put)”。而是直接请求资源,通过不同的http方法来做对应的操作。 比如: 注册: 在settings.py文件中进行注册

    2024年02月21日
    浏览(39)
  • Django DRF - 认证Authentication

    身份验证是将传入请求与一组标识凭据(例如,请求来自的用户或与其进行签名的令牌)相关联的机制。然后,权限和限制策略可以使用这些凭据来确定是否应允许该请求。 身份验证本身不会允许或不允许传入的请求,它只会标识发出请求的凭据。 认证管理一般和权限管理

    2023年04月12日
    浏览(35)
  • Django系列之DRF简单使用

    models.py serializers.py app01/views.py project/urls.py app01/urls.py 使用 SimpleRouter() 可以帮我们实现五个基础的 action 方法: {“get”: “list”, “post”: “create”, “get/id”: “retrieve”, “put”: “update”, “delete”: “`destroy”} 如果需要增加一些其他的路由视图,就需要用 action 声明了。

    2024年02月15日
    浏览(35)
  • Django系列之DRF搜索和过滤

    1. model之间关系 2. DRF搜索 在DRF中使用搜索功能,只需要在 viewsets 视图类中定义 filter_backends 和 search_fields 即可使用。 filter_backends :后端使用的搜索和过滤类。 search_fields :要执行搜索条件的字段,搜索为模糊查询(要在哪些字段上执行模糊查询,支持多表连表查询)。 对应

    2024年02月07日
    浏览(40)
  • Django DRF - 【Token】认证基本使用

    Django Rest Framework Token 是Django Rest Framework中的一个扩展,用于实现用户认证和授权。它为每个用户生成一个唯一的Token,并将其存储在数据库中。在用户进行API请求时,用户需要在请求的HTTP Header中包含Token,这样服务器就可以验证用户的身份。 迁移完成会生成 authtoken_token 这张

    2024年02月12日
    浏览(34)
  • 【Django 05】Django-DRF(ModelViewSet)、路由组件、自定义函数

    ModelViewSet 是 Django REST framework 提供的一个视图集类,它封装了常见的模型操作方法。 模型类提供了默认的增删改查功能。 它继承自 GenericViewSet 、 ListModelMixin 、 RetrieveModelMixin 、 CreateModelMixin 、 UpdateModelMixin 、 DestoryModelMixin 。 知识点 请求 url 特点 GenericViewSet 提供一组通用的

    2024年02月08日
    浏览(42)
  • Django_rest_framework-drf 笔记

    Django-drf-序列化器高级用法之SerializerMethodField - 知乎 (zhihu.com) 一句话: search_fields  里的字段,是做模糊查询的字段; filter_fields  里的字段,是做精确查询的字段。 科普search_fields与filter_fields的区别_空气中的臭氧的博客-CSDN博客 一句话: related_name = \\\'test\\\' publish_obj.test.all() 

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包