GVKun编程网logo

python框架django的数据库的正向生成和反向生成(django反向生成model)

222

对于想了解python框架django的数据库的正向生成和反向生成的读者,本文将提供新的信息,我们将详细介绍django反向生成model,并且为您提供关于068.Python框架Django之DRF

对于想了解python框架django的数据库的正向生成和反向生成的读者,本文将提供新的信息,我们将详细介绍django反向生成model,并且为您提供关于068.Python框架Django之DRF视图集使用、C # WebService简单使用实例--关于WSDL文件的正向反向生成、Django 两张表的正向查找和反向查找、Django 中反向生成 models的有价值信息。

本文目录一览:

python框架django的数据库的正向生成和反向生成(django反向生成model)

python框架django的数据库的正向生成和反向生成(django反向生成model)

正向生成,指的是先创建model.py文件,然后通过django内置的编译器,在数据库如mysql中创建出符合model.py的表。

反向生成,指的是先在数据库中create table,然后通过django内置的编译器,生成model代码。

首先创建django工程以及app

创建django工程,名字是wechat

django-admin.py startproject wechat

然后生成app

python manage.py startapp datatest

配置app以及数据库

配置app(在settings.py的INSTALLED_APPS配置app)

# Application definition

INSTALLED_APPS = [
    ''django.contrib.admin'',
    ''django.contrib.auth'',
    ''django.contrib.contenttypes'',
    ''django.contrib.sessions'',
    ''django.contrib.messages'',
    ''django.contrib.staticfiles'',
    ''datatest'',
]

配置数据库(在settings.py中配置数据库)

# 这是MySQL的配置连接方式,其他数据库在这个配置代码的上方有个地址
DATABASES = {
    ''default'': {
        ''ENGINE'': ''django.db.backends.postgresql'',
        ''NAME'': ''jmj'',
        ''USER'': ''root'',
        ''PASSWORD'': ''root'',
        ''HOST'': ''127.0.0.1'',
        ''PORT'': ''3306'',
    }
}

正向生成

在datatest app的目录下创建model.py

from django.db import models
 
class AlarmGroup(models.Model):
  group_name = models.CharField(primary_key=True, max_length=250)
  group_des = models.TextField(blank=True, null=True)
  members = models.TextField(blank=True, null=True)
  timestamp = models.DateTimeField()

  执行正向生成命令

python manage.py makemigrations
python manage.py migrate

反向生成

首先在数据库中创建表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `tel` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `dept` int(5) NOT NULL,
  `wechatid` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `fk_user_dept`(`dept`) USING BTREE,
  CONSTRAINT `fk_user_dept` FOREIGN KEY (`dept`) REFERENCES `dept` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

然后执行命令,生成model.py代码

python manage.py inspectdb

以上就是django框架的数据库整合,希望能够帮助到大家

 

068.Python框架Django之DRF视图集使用

068.Python框架Django之DRF视图集使用

一 视图集与路由的使用

使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:

  • list() 提供一组数据

  • retrieve() 提供单个数据

  • create() 创建数据

  • update() 保存数据

  • destory() 删除数据

  ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。

  视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。

1.1 常用的视图集父类

1 ViewSet

  • 继承自APIView 与 ViewSetMixin作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
  • ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{''get'':''list''})的映射处理工作。
  • 在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。

2 GenericViewSet

  使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与GenericAPIView,所以还需要继承GenericAPIView。

  GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIView与ViewSetMixin,在实现了调用as_view()时传入字典(如{''get'':''list''})的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。

3.ModelViewSet

  继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

4.ReadOnlyModelViewSet

  继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。

1.2 视图集初步使用

创建一个子应用app

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py startapp collect

注册

INSTALLED_APPS = [
    ''django.contrib.admin'',
    ''django.contrib.auth'',
    ''django.contrib.contenttypes'',
    ''django.contrib.sessions'',
    ''django.contrib.messages'',
    ''django.contrib.staticfiles'',
    ''rest_framework'',
    ''students.apps.StudentsConfig'',
    ''ser.apps.SerConfig'',
    ''req.apps.ReqConfig'',
    ''collect.apps.CollectConfig'',
]

路由分发

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path(''admin/'', admin.site.urls),
    path(''student/'',include("students.urls")),
    path(''ser/'',include("ser.urls")),
    path(''req/'', include("req.urls")),
    path(''collect/'', include("collect.urls")),
]

路由配置

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/urls.py

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
]

序列化文件

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/serializers.py 

from students.models import Student
from rest_framework import serializers


class StudentModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Student
        fields = ["id", "name", "age", "sex"]
        extra_kwargs = {
            "name": {"max_length": 10, "min_length": 4},
            "age": {"max_value": 150, "min_value": 0},
        }

    def validate_name(self, data):
        if data == "root":
            raise serializers.ValidationError("用户名不能为root!")
        return data

    def validate(self, attrs):
        name = attrs.get(''name'')
        age = attrs.get(''age'')

        if name == "alex" and age == 22:
            raise serializers.ValidationError("alex在22时的故事。。。")

        return attrs

视图文件

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)

访问http://127.0.0.1:8000/collect/student1/可以获取五条数据

 数据库中数据

mysql> select * from tb_student;

修改id=5的sex为false

数据库现有数据

获取5个男性的数据

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)

配置路由

不要在同一个路由的as_view中书写两个同样的键的http请求,会产生覆盖!!!

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
]

访问http://127.0.0.1:8000/collect/student1/get_5_female/结果如下

 

获取一条

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r''^student1/(?P<pk>\d+)/$'', views.Student1ViewSet.as_view({"get": "get_one"})),
]

配置视图

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

POSTMAN调试,访问http://127.0.0.1:8000/collect/student1/5/

 

GenericViewSet视图 

URL路由配置

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r''^student1/(?P<pk>\d+)/$'', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path(''student2/'', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path(''student2/get_5_female/'', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
]

视图文件

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer
from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

POSTMAN调试

1.3 GenericViewSet结合模型类

可以和模型类进行组合快速生成基本的API接口

url路由配置

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r''^student1/(?P<pk>\d+)/$'', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path(''student2/'', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path(''student2/get_5_female/'', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet和模型类进行组合快速生成基本的API接口,当使用get,触发list的方法,当使用POST请求,触发create方法
    path("students3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
]

视图文件

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    
from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

POSTMAN调试

get请求

 POST请求

 

 查看数据库

 

1.4 ModelViewSet配置

url配置

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r''^student1/(?P<pk>\d+)/$'', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path(''student2/'', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path(''student2/get_5_female/'', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet和模型类进行组合快速生成基本的API接口
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 默认提供了5个API接口
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
]

views

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

POSTMAN调试

获取所有

 POST添加

数据库

PUT修改

数据库

delete删除

 

数据库

mysql> select * from tb_student;
+----+------------+-----+-----+------------+-------------------+
| id | name       | sex | age | class_null | description       |
+----+------------+-----+-----+------------+-------------------+
|  1 | 令狐冲     |   1 |  18 | 205        | hello mysqlf      |
|  2 | 任我行     |   1 |  55 | 203        | hello let me go   |
|  3 | 李寻欢     |   1 |  33 | 207        | be happy lee      |
|  5 | limochu    |   0 |  36 | 208        | Don’t Worry Lee   |
|  6 | mchaofeng  |   1 |  26 |            |                   |
|  7 | yangguo    |   1 |  25 |            |                   |
|  8 | xiaolongnv |   0 |  25 |            |                   |
+----+------------+-----+-----+------------+-------------------+

1.5 ReadOnlyModelViewSet配置

url路由配置

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r''^student1/(?P<pk>\d+)/$'', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path(''student2/'', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path(''student2/get_5_female/'', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet和模型类进行组合快速生成基本的API接口
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 默认提供了5个API接口
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    # ReadOnlyModelViewSet
    path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path(r"^student5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
]

view视图配置

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

只有get方法

 

获取一条

二 路由类的使用

有了视图集以后,视图文件中多个视图类可以合并成一个,但是,路由的代码就变得复杂了, 需要我们经常在as_view方法 ,编写http请求和视图方法的对应关系, 事实上,在路由中,DRF也提供了一个路由类给我们对路由的代码进行简写。 当然,这个路由类仅针对于 视图集 才可以使用。

2.1 路由类基本配置

url路由配置

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r''^student1/(?P<pk>\d+)/$'', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path(''student2/'', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path(''student2/get_5_female/'', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet和模型类进行组合快速生成基本的API接口
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 默认提供了5个API接口
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    # ReadOnlyModelViewSet
    path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path(r"^student5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
]

# 路由类默认只会给视图集中的基本5个API生成地址[ 获取一条,获取多条,添加.删除,修改数据 ]
from rest_framework.routers import DefaultRouter
# 实例化路由类
router = DefaultRouter()
# router.register("访问地址前缀","视图集类","访问别名")
# 注册视图视图集类
router.register("student7", views.Student7ModelViewSet)

print(router.urls)
# 把路由列表注册到django项目中
urlpatterns += router.urls

views视图文件

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

重启之后,查看print打印内容

[
<URLPattern ''^student7/$'' [name=''student-list'']>,
<URLPattern ''^student7\.(?P<format>[a-z0-9]+)/?$'' [name=''student-list'']>,
<URLPattern ''^student7/(?P<pk>[^/.]+)/$'' [name=''student-detail'']>,
<URLPattern ''^student7/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$'' [name=''student-detail'']>,
<URLPattern ''^$'' [name=''api-root'']>,
<URLPattern ''^\.(?P<format>[a-z0-9]+)/?$'' [name=''api-root'']>
]







POSTMAN调试

获取所有

2.2 自定义方法并调用

添加进views方法中 

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # methods 指定允许哪些http请求访问当前视图方法
    # detail  指定生成的路由地址中是否要夹带pk值,True为需要
    # @action(methods=[''get''], detail=False)
    # def get_4(self, request):
    @action(methods=[''get''], detail=True)
    def get_5(self, request, pk):
        serilizer = self.get_serializer(instance=self.get_queryset().get(pk=pk))
        return Response(serilizer.data)

重启查看打印信息

[
<URLPattern ''^student7/$'' [name=''student-list'']>,
<URLPattern ''^student7\.(?P<format>[a-z0-9]+)/?$'' [name=''student-list'']>,
<URLPattern ''^student7/(?P<pk>[^/.]+)/$'' [name=''student-detail'']>,
<URLPattern ''^student7/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$'' [name=''student-detail'']>,
<URLPattern ''^student7/(?P<pk>[^/.]+)/get_5/$'' [name=''student-get-5'']>,
<URLPattern ''^student7/(?P<pk>[^/.]+)/get_5\.(?P<format>[a-z0-9]+)/?$'' [name=''student-get-5'']>,
<URLPattern ''^$'' [name=''api-root'']>,
<URLPattern ''^\.(?P<format>[a-z0-9]+)/?$'' [name=''api-root'']>]







POSTMAN访问自定义方法

 

2.3 在一个视图类调用多个视图划器类 

url路由配置

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r''^student1/(?P<pk>\d+)/$'', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path(''student2/'', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path(''student2/get_5_female/'', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet和模型类进行组合快速生成基本的API接口
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 默认提供了5个API接口
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    # ReadOnlyModelViewSet
    path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path(r"^student5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
    # 一个视图类中调用多个序列化器
    path("student8/", views.Student8GenericAPIView.as_view()),
]

# 路由类默认只会给视图集中的基本5个API生成地址[ 获取一条,获取多条,添加.删除,修改数据 ]
from rest_framework.routers import DefaultRouter
# 实例化路由类
router = DefaultRouter()
# router.register("访问地址前缀","视图集类","访问别名")
# 注册视图视图集类
router.register("student7", views.Student7ModelViewSet)

print(router.urls)
# 把路由列表注册到django项目中
urlpatterns += router.urls

view视图配置

from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # methods 指定允许哪些http请求访问当前视图方法
    # detail  指定生成的路由地址中是否要夹带pk值,True为需要
    # @action(methods=[''get''], detail=False)
    # def get_4(self, request):
    @action(methods=[''get''], detail=True)
    def get_5(self, request, pk):
        serilizer = self.get_serializer(instance=self.get_queryset().get(pk=pk))
        return Response(serilizer.data)

from rest_framework.generics import GenericAPIView
from collect.serializers import StudentInfoModelSerializer
class Student8GenericAPIView(GenericAPIView):
    queryset = Student.objects.all()

    # GenericAPI内部调用序列化器的方法,我们可以重写这个方法来实现根据不同的需求来调用不同的序列化器
    def get_serializer_class(self):
        if self.request.method == "GET":
            # 2个字段
            return StudentInfoModelSerializer
        return StudentModelSerializer

    def get(self, request):
        """获取所有数据的id和name"""
        student_list = self.get_queryset()
        serializer = self.get_serializer(instance=student_list, many=True)
        # serializer = StudentInfoModelSerializer(instance=student_list, many=True)
        return Response(serializer.data)

    def post(self, request):
        """添加数据"""
        data = request.data
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

序列化类

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/serializers.py

from students.models import Student
from rest_framework import serializers

class StudentModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ["id", "name", "age", "sex"]
        extra_kwargs = {
            "name": {"max_length": 10, "min_length": 4},
            "age": {"max_value": 150, "min_value": 0},
        }
    def validate_name(self, data):
        if data == "root":
            raise serializers.ValidationError("用户名不能为root!")
        return data
    def validate(self, attrs):
        name = attrs.get(''name'')
        age = attrs.get(''age'')

        if name == "alex" and age == 22:
            raise serializers.ValidationError("alex在22时的故事。。。")
        return attrs

class StudentInfoModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ["id", "name"]

访问http://127.0.0.1:8000/collect/student8/

只有两个字段

2.4 视图集内使用多个序列化类

url配置

from  django.urls import path,re_path
from collect import views

urlpatterns = [
    #ViewSet
    path(''student1/'', views.Student1ViewSet.as_view({"get": "get_5"})),
    path(''student1/get_5_female/'', views.Student1ViewSet.as_view({"get": "get_5_female"})),
    re_path(r''^student1/(?P<pk>\d+)/$'', views.Student1ViewSet.as_view({"get": "get_one"})),
    # GenericViewSet
    path(''student2/'', views.Student3GenericViewSet.as_view({"get": "get_5"})),
    path(''student2/get_5_female/'', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),
    # GenericViewSet和模型类进行组合快速生成基本的API接口
    path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),
    # ModelViewSet 默认提供了5个API接口
    path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),
    re_path(r"^student4/(?P<pk>\d+)/$",
            views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
    # ReadOnlyModelViewSet
    path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path(r"^student5/(?P<pk>\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),
    # 一个视图类中调用多个序列化器
    path("student8/", views.Student8GenericAPIView.as_view()),
    # 一个视图集中调用多个序列化器
    path("student9/", views.Student9ModelViewSet.as_view({"get": "list"})),
    re_path(r"^student9/(?P<pk>\d+)/$", views.Student9ModelViewSet.as_view({"get": "retrieve"})),
]

# 路由类默认只会给视图集中的基本5个API生成地址[ 获取一条,获取多条,添加.删除,修改数据 ]
from rest_framework.routers import DefaultRouter
# 实例化路由类
router = DefaultRouter()
# router.register("访问地址前缀","视图集类","访问别名")
# 注册视图视图集类
router.register("student7", views.Student7ModelViewSet)

print(router.urls)
# 把路由列表注册到django项目中
urlpatterns += router.urls

views配置

要求:

  • 列表数据list,返回2个字段,
  • 详情数据retrieve,返回所有字段 
from django.shortcuts import render
from rest_framework.viewsets import ViewSet
from students.models import Student
from collect.serializers import StudentModelSerializer

from rest_framework.response import Response
# Create your views here.

class Student1ViewSet(ViewSet):
    def get_5(self,request):
        #取出所有,并切片操作
        queryset = Student.objects.all()[:5]
        #实例化
        serializer = StudentModelSerializer(instance=queryset,many=True)
        return Response(serializer.data)
    def get_5_female(self,request):
        queryset = Student.objects.filter(sex=False)[:5]
        serializer = StudentModelSerializer(instance=queryset, many=True)
        return Response(serializer.data)
    def get_one(self,request,pk):
        student_obj = Student.objects.get(pk=pk)
        serializer = StudentModelSerializer(instance=student_obj)
        return Response(serializer.data)

from rest_framework.viewsets import GenericViewSet
class Student3GenericViewSet(GenericViewSet):
    serializer_class = StudentModelSerializer
    queryset = Student.objects.all()
    def get_5(self, request):
        student_list = self.get_queryset()[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)
    def get_5_female(self, request):
        student_list = self.get_queryset().filter(sex=False)[:5]
        serializer = self.get_serializer(instance=student_list, many=True)
        return Response(serializer.data)

from rest_framework.mixins import ListModelMixin, CreateModelMixin
class Student4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ModelViewSet
class Student5ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.viewsets import ReadOnlyModelViewSet
class Student6ReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

from rest_framework.decorators import action
class Student7ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # methods 指定允许哪些http请求访问当前视图方法
    # detail  指定生成的路由地址中是否要夹带pk值,True为需要
    # @action(methods=[''get''], detail=False)
    # def get_4(self, request):
    @action(methods=[''get''], detail=True)
    def get_5(self, request, pk):
        serilizer = self.get_serializer(instance=self.get_queryset().get(pk=pk))
        return Response(serilizer.data)

from rest_framework.generics import GenericAPIView
from collect.serializers import StudentInfoModelSerializer
class Student8GenericAPIView(GenericAPIView):
    queryset = Student.objects.all()

    # GenericAPI内部调用序列化器的方法,我们可以重写这个方法来实现根据不同的需求来调用不同的序列化器
    def get_serializer_class(self):
        if self.request.method == "GET":
            # 2个字段
            return StudentInfoModelSerializer
        return StudentModelSerializer

    def get(self, request):
        """获取所有数据的id和name"""
        student_list = self.get_queryset()

        serializer = self.get_serializer(instance=student_list, many=True)
        # serializer = StudentInfoModelSerializer(instance=student_list, many=True)

        return Response(serializer.data)

    def post(self, request):
        """添加数据"""
        data = request.data
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

class Student9ModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    def get_serializer_class(self):
        # 本次客户端请求的视图方法名  self.action
        print(self.action)
        if self.action == "list":
            return StudentInfoModelSerializer
        return StudentModelSerializer

get获取所有,只返回两个字段

打印的结果是list

输出单个信息,会输出4个字段

方法名称

三  DRF的扩展功能

创建新的app应用

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py startapp opt

注册

INSTALLED_APPS = [
    ''django.contrib.admin'',
    ''django.contrib.auth'',
    ''django.contrib.contenttypes'',
    ''django.contrib.sessions'',
    ''django.contrib.messages'',
    ''django.contrib.staticfiles'',
    ''rest_framework'',
    ''students.apps.StudentsConfig'',
    ''ser.apps.SerConfig'',
    ''req.apps.ReqConfig'',
    ''collect.apps.CollectConfig'',
    ''opt.apps.OptConfig'',
]

配置字体

LANGUAGE_CODE = ''zh-hans''

添加路由分发

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path(''admin/'', admin.site.urls),
    path(''student/'',include("students.urls")),
    path(''ser/'',include("ser.urls")),
    path(''req/'', include("req.urls")),
    path(''collect/'', include("collect.urls")),
    path(''opt/'', include("opt.urls")),
]

3.1 用户控制

创建路由文件

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim opt/urls.py

from django.urls import path
from opt import views

urlpatterns = [
    path(''auth1/'', views.Demo1APIView.as_view()),
    path(''auth2/'', views.Demo2APIView.as_view()),
]

views文件

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#用户的认证和权限识别
class Demo1APIView(APIView):
    #只允许登录后的用户访问
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #个人中心
        return Response("个人中心")

class Demo2APIView(APIView):
    #只允许管理员访问
    permission_classes = [IsAdminUser]
    def get(self, request):
        #个人中心2
        return Response("个人中心2")

访问http://127.0.0.1:8000/opt/auth1/

创建一个admin用户进行管理

 

登录http://127.0.0.1:8000/admin/login/?next=/admin/ 

登陆后,查看http://127.0.0.1:8000/opt/auth1/和 http://127.0.0.1:8000/opt/auth2/

创建一个alex用户

使用alex登录,同时取消人员状态

然后auth1可以正常访问,但是访问http://127.0.0.1:8000/opt/auth2/

必须是一个超级管理员用户才能看见

查看数据的seeeion

 mysql> select * from django_session;

+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+
| session_key                      | session_data                                                                                                                                                                                                                                                 | expire_date                |
+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+
| fn55zqveedvfjckalewwusqny7iadhun | MWM5NDBiNmI0ZDZlYTFmZmM4MjE4YTkyODcyMWNmNTQ4NjJkNDJkNTp7Il9hdXRoX3VzZXJfaWQiOiIyIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiIwMTY2ZDUxMTFhYzU2ZTBjMWRkZDU5ZmM3MmE5ZmI1ZjcyYWY4NmMxIn0= | 2020-05-05 07:27:10.353593 |
+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+

3.2 权限Permissions控制

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。

  • 在执行视图的dispatch()方法前,会先进行视图访问权限的判断

  • 在通过get_object()获取具体对象时,会进行模型对象访问权限的判断

内置提供的权限:

  • AllowAny 允许所有用户

  • IsAuthenticated 仅通过认证的用户

  • IsAdminUser 仅管理员用户

  • IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。

可以在配置文件中全局设置默认的权限管理类,如:

REST_FRAMEWORK = {
    ....
    ''DEFAULT_PERMISSION_CLASSES'': (
        ''rest_framework.permissions.IsAuthenticated'',
    )
}

如果未指明,则采用如下默认配置

''DEFAULT_PERMISSION_CLASSES'': (
   ''rest_framework.permissions.AllowAny'',

 自定义权限

url配置

from django.urls import path,re_path
from opt import views

urlpatterns = [
    path(''auth1/'', views.Demo1APIView.as_view()),
    path(''auth2/'', views.Demo2APIView.as_view()),
    # 自定义权限
    path(''auth3/'', views.Demo3APIView.as_view()),
]

views配置

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#用户的认证和权限识别
class Demo1APIView(APIView):
    #只允许登录后的用户访问
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #个人中心
        return Response("个人中心")

class Demo2APIView(APIView):
    #只允许管理员访问
    permission_classes = [IsAdminUser]
    def get(self, request):
        #个人中心2
        return Response("个人中心2")

# 自定义权限
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        针对访问视图进行权限判断
        :param request: 本次操作的http请求对象
        :param view:  本次访问路由对应的视图对象
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """个人中心3"""
        return Response("个人中心3")

创建xiaoming用户

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py createsuperuser

使用root登录访问auth3

使用ixaoming用户登录访问

3.3  限流Throttling

可以对接口访问的频次进行限制,以减轻服务器压力。

一般用于付费购买次数,投票等场景使用.

可以在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES进行全局配置

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim drf_demo/settings.py 

REST_FRAMEWORK = {
    # 限流
    ''DEFAULT_THROTTLE_CLASSES'': (  # 对全局进行设置
        ''rest_framework.throttling.AnonRateThrottle'',
        ''rest_framework.throttling.UserRateThrottle''
    ),
    ''DEFAULT_THROTTLE_RATES'': {
        ''anon'': ''3/hour'',
        ''user'': ''3/minute'',
    }
}

DEFAULT_THROTTLE_RATES 可以使用 second, minute, hour 或day来指明周期。

URL文件

from django.urls import path,re_path
from opt import views

urlpatterns = [
    path(''auth1/'', views.Demo1APIView.as_view()),
    path(''auth2/'', views.Demo2APIView.as_view()),
    # 自定义权限
    path(''auth3/'', views.Demo3APIView.as_view()),
    # 限流
    path(''auth4/'', views.Demo4APIView.as_view()),
]

views视图文件

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#用户的认证和权限识别
class Demo1APIView(APIView):
    #只允许登录后的用户访问
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #个人中心
        return Response("个人中心")

class Demo2APIView(APIView):
    #只允许管理员访问
    permission_classes = [IsAdminUser]
    def get(self, request):
        #个人中心2
        return Response("个人中心2")

# 自定义权限
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        针对访问视图进行权限判断,必须使用xiaoming用户
        :param request: 本次操作的http请求对象
        :param view:  本次访问路由对应的视图对象
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """个人中心3"""
        return Response("个人中心3")

# 限流
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]  # 全局配置后,这里就不用指定
    def get(self, request):
        """投票页面"""
        return Response("投票页面")

访问auth4

当超过3次

 

 注销用户,使用匿名用户次数超标

 

3.4  过滤Filtering

对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。

安装django-filter

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# pip3 install django-filter

注册

INSTALLED_APPS = [
    ''django.contrib.admin'',
    ''django.contrib.auth'',
    ''django.contrib.contenttypes'',
    ''django.contrib.sessions'',
    ''django.contrib.messages'',
    ''django.contrib.staticfiles'',
    
    ''rest_framework'',
    ''django_filters'',  # 需要注册应用,
    
    ''students.apps.StudentsConfig'',
    ''ser.apps.SerConfig'',
    ''req.apps.ReqConfig'',
    ''collect.apps.CollectConfig'',
    ''opt.apps.OptConfig'',
]

配置url路由

from django.urls import path,re_path
from opt import views

urlpatterns = [
    path(''auth1/'', views.Demo1APIView.as_view()),
    path(''auth2/'', views.Demo2APIView.as_view()),
    # 自定义权限
    path(''auth3/'', views.Demo3APIView.as_view()),
    # 限流
    path(''auth4/'', views.Demo4APIView.as_view()),
    # 过滤
    path(''data5/'', views.Demo5APIView.as_view()),
]

views视图

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#用户的认证和权限识别
class Demo1APIView(APIView):
    #只允许登录后的用户访问
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #个人中心
        return Response("个人中心")

class Demo2APIView(APIView):
    #只允许管理员访问
    permission_classes = [IsAdminUser]
    def get(self, request):
        #个人中心2
        return Response("个人中心2")

# 自定义权限
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        针对访问视图进行权限判断,必须使用xiaoming用户
        :param request: 本次操作的http请求对象
        :param view:  本次访问路由对应的视图对象
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """个人中心3"""
        return Response("个人中心3")

# 限流
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]  # 全局配置后,这里就不用指定
    def get(self, request):
        """投票页面"""
        return Response("投票页面")

# 过滤
from rest_framework.generics import GenericAPIView, ListAPIView
from students.models import Student
from opt.serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
# ''django_filters.rest_framework.DjangoFilterBackend''
class Demo5APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend]  # 全局配置后,这里就不用指定了。
    filter_fields = [''age'', "id"]  # 声明过滤字段

复制一个序列化类

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# cp collect/serializers.py     opt/

setting设置

REST_FRAMEWORK = {
    # 限流
    ''DEFAULT_THROTTLE_CLASSES'': (  # 对全局进行设置
        ''rest_framework.throttling.AnonRateThrottle'',
        ''rest_framework.throttling.UserRateThrottle''
    ),
    ''DEFAULT_THROTTLE_RATES'': {
        ''anon'': ''3/hour'',
        ''user'': ''3/minute'',
    }
    ''DEFAULT_FILTER_BACKENDS'': (''django_filters.rest_framework.DjangoFilterBackend'',)
}

访问http://127.0.0.1:8000/opt/data5/

 

 点击过滤器

 

提交

3.5 排序Ordering

对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。

使用方法:

  在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。

前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

 路由配置

from django.urls import path,re_path
from opt import views

urlpatterns = [
    path(''auth1/'', views.Demo1APIView.as_view()),
    path(''auth2/'', views.Demo2APIView.as_view()),
    # 自定义权限
    path(''auth3/'', views.Demo3APIView.as_view()),
    # 限流
    path(''auth4/'', views.Demo4APIView.as_view()),
    # 过滤
    path(''data5/'', views.Demo5APIView.as_view()),
    # 排序
    path(''data6/'', views.Demo6APIView.as_view()),
]

views视图配置

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#用户的认证和权限识别
class Demo1APIView(APIView):
    #只允许登录后的用户访问
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #个人中心
        return Response("个人中心")

class Demo2APIView(APIView):
    #只允许管理员访问
    permission_classes = [IsAdminUser]
    def get(self, request):
        #个人中心2
        return Response("个人中心2")

# 自定义权限
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        针对访问视图进行权限判断,必须使用xiaoming用户
        :param request: 本次操作的http请求对象
        :param view:  本次访问路由对应的视图对象
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """个人中心3"""
        return Response("个人中心3")

# 限流
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]  # 全局配置后,这里就不用指定
    def get(self, request):
        """投票页面"""
        return Response("投票页面")

# 过滤
from rest_framework.generics import GenericAPIView, ListAPIView
from students.models import Student
from opt.serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
# ''django_filters.rest_framework.DjangoFilterBackend''
class Demo5APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend]  # 全局配置后,这里就不用指定了。
    filter_fields = [''age'', "id"]  # 声明过滤字段

# 排序
from rest_framework.filters import OrderingFilter


class Demo6APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend, OrderingFilter]  # 局部配置会覆盖全局配置
    filter_fields = [''id'', "sex"]
    ordering_fields = [''id'', "age"]

访问http://127.0.0.1:8000/opt/data6/

点击过滤器

 

3.6 分页Pagination

  REST framework提供了分页的支持。

  我们可以在配置文件中设置全局的分页方式,如:

REST_FRAMEWORK = {
    ''DEFAULT_PAGINATION_CLASS'':  ''rest_framework.pagination.PageNumberPagination'',
    ''PAGE_SIZE'': 100  # 每页数目
}

 也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_clas属性来指明。

  opt下的urls.py
from django.urls import path,re_path
from opt import views

urlpatterns = [
    path(''auth1/'', views.Demo1APIView.as_view()),
    path(''auth2/'', views.Demo2APIView.as_view()),
    # 自定义权限
    path(''auth3/'', views.Demo3APIView.as_view()),
    # 限流
    path(''auth4/'', views.Demo4APIView.as_view()),
    # 过滤
    path(''data5/'', views.Demo5APIView.as_view()),
    # 排序
    path(''data6/'', views.Demo6APIView.as_view()),
    # 分页
    path(''data7/'', views.Demo7APIView.as_view()),
]

views视图文件

from django.shortcuts import render
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser

#用户的认证和权限识别
class Demo1APIView(APIView):
    #只允许登录后的用户访问
    permission_classes = [IsAuthenticated]
    def get(self, request):
        #个人中心
        return Response("个人中心")

class Demo2APIView(APIView):
    #只允许管理员访问
    permission_classes = [IsAdminUser]
    def get(self, request):
        #个人中心2
        return Response("个人中心2")

# 自定义权限
from rest_framework.permissions import BasePermission

class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """
        针对访问视图进行权限判断,必须使用xiaoming用户
        :param request: 本次操作的http请求对象
        :param view:  本次访问路由对应的视图对象
        :return:
        """
        if request.user.username == "xiaoming":
            return True
        return False

class Demo3APIView(APIView):
    permission_classes = [MyPermission]

    def get(self, request):
        """个人中心3"""
        return Response("个人中心3")

# 限流
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
class Demo4APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]  # 全局配置后,这里就不用指定
    def get(self, request):
        """投票页面"""
        return Response("投票页面")

# 过滤
from rest_framework.generics import GenericAPIView, ListAPIView
from students.models import Student
from opt.serializers import StudentModelSerializer
from django_filters.rest_framework import DjangoFilterBackend
# ''django_filters.rest_framework.DjangoFilterBackend''
class Demo5APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend]  # 全局配置后,这里就不用指定了。
    filter_fields = [''age'', "id"]  # 声明过滤字段

# 排序
from rest_framework.filters import OrderingFilter


class Demo6APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    filter_backends = [DjangoFilterBackend, OrderingFilter]  # 局部配置会覆盖全局配置
    filter_fields = [''id'', "sex"]
    ordering_fields = [''id'', "age"]

#分页
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination

"""1. 自定义分页器,定制分页的相关配置"""
"""
# 页码分页  PageNumberPagination
前端访问形式:GET  http://127.0.0.1:8000/opt/data7/?page=4

page=1   limit 0,10
page=2   limit 10,20

# 偏移量分页  LimitOffsetPagination
前端访问形式:GET  http://127.0.0.1:8000/opt/data7/?start=4&size=3

start=0  limit 0,10
start=10 limit 10,10
start=20 limit 20,10
"""


class StandardPageNumberPagination(PageNumberPagination):
    """分页相关配置"""
    page_query_param = "page"          # 设置分页页码关键字名
    page_size = 3                      # 设置每页显示数据条数
    page_size_query_param = "size"     # 设置指定每页大小的关键字名
    max_page_size = 5                  # 设置每页显示最大值


class StandardLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2                  # 默认限制,默认值与PAGE_SIZE设置一致
    limit_query_param = "size"         # limit参数名
    offset_query_param = "start"       # offset参数名
    max_limit = 5                      # 最大limit限制


class Demo7APIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer
    # 分页
    # 页码分页类
    pagination_class = StandardPageNumberPagination
    # 偏移量分页类
    # pagination_class = StandardLimitOffsetPagination

访问http://127.0.0.1:8000/opt/data7/

 

访问http://127.0.0.1:8000/opt/data7/?page=1&size=8,就是每一页显示8个数据

但是只显示五个,是在代码设置最大显示5个,当设置显示8个时,不会生效,只会显示5个


参考:https://www.cnblogs.com/Michael--chen/p/11222143.html,老男孩教育:https://www.oldboyedu.com/ 

C # WebService简单使用实例--关于WSDL文件的正向反向生成

C # WebService简单使用实例--关于WSDL文件的正向反向生成

1.1 背景

     webService 作为一种语言无关性的程序与程序之间的通讯方式,曾经使用非常广泛,随着微软无语的迭代更新的速度,已经不是那么流行。之前主要都是被人提供一个URL,我在vs里面添加服务引用,IDE自动帮我生成相关的代码。这样就可以调用别人的方法了,可是这建立在对方的web服务处于打开状态下,你才能添加服务引用,并生成相关的代码。可是有一天别人的web服务并没有部署,并向你扔了一个WSDL文件,我去!!其中心酸的弯路不再废话,主要记录下如何从wsdl文件生成客户端代码,以及如何通过url生成wsdl文件。

 

1.2 如何通过url生成wsdl文件

   有时候作为服务的提供方,我只是在本地将web 服务的方法写好调试好,并没有部署到服务器上,这时候客户端的那个小伙子还在等着我们提供给他web 引用呢,这个时候 只有我部署完毕,他的进度才能继续。哈哈,这个时候就是这个wsdl文件站出来发挥作用的时候了。为了演示,就要自己新建一个简单的web Service。

   

               里面的web方法如下,不用动:

              

         开启服务之后,地址栏里面会有url如下:

       这个时候wsdl文件已经生成了,可是我在这个项目的每个文件夹下都找遍了都没有,去LG百度上搜索得到信息是:任何 一门语言或是IDE在其生成的时候wsdl文件就已经生成了,fuck,Google了一下原来是要在网址后面加一个?WSDL,注意中间不能有空格

回车一下,这个时候我们看到下面这个xml一样的页面,这个时候右键--另存为。注意不要cory到txt档里面,再改文件名后缀这样丢给被人的时候,生成代码的时候会报错。

 

 

   另存为

   

    好了到此这个wsdl文件已经生成,这个时候可以关掉代码,把wsdl文件丢给下一个小伙子了。

 

1.3 如何通过wsdl文件生成指定语言的代码

    有个这个wsdl文件,就可以生成java的,C#的,php的等等的代码了,主要演示一下vs下面怎么用,首先要在工具--外部工具--添加 ,里面配置个wsdl.exe的工具,你配置好之后在工具里面就能找的到,大部分小伙伴可能还没用过这个外部工具吧,详细的如何配置

Google或者百度一下都可以。配置好之后如下:

 

  这个时候我们要事先把被人丢过来的wsdl文件放到一个好找的文件夹下:

 

 

这个时候再新建一个winform客户端测试项目,新建一个文件夹,选中文件夹,再选中工具--刚刚配置的那个工具,点击确认。这样一个cs文件就生成到你选中的文件下面去了,选中文件夹--添加现有项,把代码显示出来。

   

如果出现以下输出没报错说明生成成功了。

 

 

这个时候客户端的这个我们刚自动生成的mybmm.cs的文件会报错:web.servers找不到,这个时候需要手动引用一下这个dll。

 

  到此大功告成,收工,慢着还需要测试一下。

1.4 测试引用

     在客户端拖一个按钮试一下。

    

   显示可以调用,和添加服务引用的效果一样,不过文件夹目录那里没有服务引用的痕迹。

 

 

Django 两张表的正向查找和反向查找

Django 两张表的正向查找和反向查找

Django的多表查询
假设有模型

class Category(models.Model):
    id = models.CharField(primary_key = True,max_length = 255)
    type_name = models.CharField(max_length = 255)
    def __str__(self):
        return self.id+"."+self.type_name
    class Meta:
        db_table = "category"

class BookList(models.Model):
    name = models.CharField(primary_key = True,max_length = 255) #书名
    author = models.CharField(max_length = 255)                 #作者
    read_num = models.CharField(max_length = 255)                  #阅读人数
    book_type = models.ForeignKey(Category, models.DO_NOTHING)  #外键 ,书的类别
    
    class Meta:
        db_table = "booklist"
  • 正向查询就是查询对象的主体是Category,要查询Category模型对应表里的数据
  • 反向查询就是查询对象的主体是Category,要查询的是BookList里的数据

正向查找

t = models.Category.objects.filter()
>>> <QuerySet [<Category: 1.玄幻魔法>, <Category: 2.武侠修真>, <Category: 3.都市言情>, <Category: 4.历史穿越>, <Category: 5.恐怖悬疑>, <Category: 6.游戏竞技>,
<Category: 7.军事科幻>, <Category: 8.女生频道>]>

反向查找

t[0].booklist_set.values("name")
>>> <QuerySet [{''name'': ''七世悟道''}, {''name'': ''关于在异界求生这件小事''}, {''name'': ''刀镇星河''}, {''name'': ''变身之女侠时代''}, {''name'': ''吾名丹尊万木''}, {''name'':
''基因贩卖商''}, {''name'': ''天地霸体诀''}, {''name'': ''天革''}, {''name'': ''天骄狂尊''}, {''name'': ''太古魂帝''}, {''name'': ''守域奇缘''}, {''name'': ''悲剧发生前[快穿]''}, {''name'': ''我有一张沾沾卡''}, {''name'': ''我的绝美御姐老婆''}, {''name'': ''我的美女俏老婆''}, {''name'': ''我的铆钢蒸汽时代''}, {''name'': ''战道天图''}, {''name'': ''无敌从满级属性开始''}, {''name'': ''极品朋友圈''}, {''name'': ''残魄御天''}, ''...(remaining elements truncated)...'']>.

反向查找的更简单的步骤,可以使用select_related方法实现

#t = model.Category.objects.select_related("type_name").values("name")

Django 中反向生成 models

Django 中反向生成 models

我们在展示 django ORM 反向生成之前,我们先说一下怎么样正向生成代码。

正向生成,指的是先创建 model.py 文件,然后通过 django 内置的编译器,在数据库如 mysql 中创建出符合 model.py 的表。

反向生成,指的是先在数据库中 create table,然后通过 django 内置的编译器,生成 model 代码。

一 准备工作

创建 django 工程以及 app

创建 django 工程,名字是 helloworld

django-admin.py startproject helloworld

创建 app,名字是 test

python manage.py startapp hello

配置数据库

在 settings.py 的 INSTALLED_APPS 配置 app

# Application definition  
  
INSTALLED_APPS = [  
    ''django.contrib.admin'',  
    ''django.contrib.auth'',  
    ''django.contrib.contenttypes'',  
    ''django.contrib.sessions'',  
    ''django.contrib.messages'',  
    ''django.contrib.staticfiles'',  
    ''hello'',  
]  

在 settings.py 中配置数据库

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

二 正向生成

在 hello app 的目录下创建 model.py

from django.db import models

class AlarmGroup(models.Model):
    group_name = models.CharField(primary_key=True, max_length=250)
    group_des = models.TextField(blank=True, null=True)
    members = models.TextField(blank=True, null=True)
    timestamp = models.DateTimeField()

执行命令正向生成

python manage.py makemigrations
python manage.py migrate

三 反向生成 ORM

先在数据库中创建表

CREATE TABLE `alarm_group` (
  `group_name` varchar(250) NOT NULL,
  `group_des` blob,
  `members` blob,
  `timestamp` datetime NOT NULL,
  `on_duty` blob,
  `leader` blob,
  PRIMARY KEY (`group_name`)
) ENGIN

然后执行命令,生成 model.py 代码

python manage.py inspectdb

生成的代码 model.py 如下

class AlarmGroup(models.Model):
    group_name = models.CharField(primary_key=True, max_length=250)
    group_des = models.TextField(blank=True, null=True)
    members = models.TextField(blank=True, null=True)
    timestamp = models.DateTimeField()

    class Meta:
        managed = False
        db_table = ''alarm_group''

将代码导入到项目中

python manage.py inspectdb > hello/models.py

根据表名生成

python manage.py inspectdb school_schoolinfo

 

我们今天的关于python框架django的数据库的正向生成和反向生成django反向生成model的分享已经告一段落,感谢您的关注,如果您想了解更多关于068.Python框架Django之DRF视图集使用、C # WebService简单使用实例--关于WSDL文件的正向反向生成、Django 两张表的正向查找和反向查找、Django 中反向生成 models的相关信息,请在本站查询。

本文标签: