• 一.7.服务器之分页和搜索应用


    一.分页:

    1.写python脚本的应用示例--获取用户py脚本

    #!/bin/python
    #sys系统包帮我加环境变量的目录,os包帮我找路径
    import sys
    import os
    #(1)加载django的配置文件settings.py即找到django的项目目录:os.path.realpath(__file__)是当前文件的路径即add_user.py的路径--/vagrant/devops/scripts/add_user.py,往上退一层os.path.dirname(add_user.py)是它的上一层目录script的目录--/vagrant/devops/scripts,再往上退一层就是/vagrant/devops这个目录,settings.py就在这个目录中
    project_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
    #(2)加上述的目录加入到环境变量中sys.path:
    sys.path.append(project_dir)
    #(3)加入到django环境变是中:
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "devops.settings")
    
    import django
    #初始化django:
    django.setup()
    from django.contrib.auth import get_user_model
    User = get_user_model()
    
    def get_users():
        for user in User.objects.all():
            print(user.username)
    
    if __name__ == "__main__":
        get_users()

    2.如下图测试页面:我的用户api页面中它是一次把所有用户展示并无分页,其实drf的viewset中已内置,我们只需调用分页器即可

     (1)apps/users/views.py中:导入分页类即可:

    from django.shortcuts import render
    from rest_framework import viewsets
    #from django.contrib.auth.models import User 以后建议换成下面这种写法
    from django.contrib.auth import get_user_model
    from .serializers import UserSerializer
    from rest_framework.pagination import PageNumberPagination
    
    User = get_user_model()
    class UserViewset(viewsets.ReadOnlyModelViewSet):
        '''
        这个用户资源的viewset会给外面暴露两个接口retrieve和list
        retrieve:
            返回指定用户信息对象--单个对象的字段是在用户序列化类serializers.py中定义
         list:
            返回用户列表--列表的字段的字段是在用户序列化类serializers.py中定义
        '''
        #1.指定queryset
        queryset = User.objects.all()
        #2.指定序列化类
        serializer_class = UserSerializer
        #引用分页类:
        pagination_class = PageNumberPagination

    (2)settings.py中配置drf分页的每页数据量:

    REST_FRAMEWORK = {
     'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
        'PAGE_SIZE':10
    }

    运行后效果如下:

    3.自定分页器高级用法

    (1)app/users/pagination.py:

    from rest_framework.pagination import PageNumberPagination
    
    
    class Pagination(PageNumberPagination):
        def get_page_size(self, request):
            try:
                page_size = int(request.query_params.get("page_size", -1))
                if page_size < 0:
                    return self.page_size
                return page_size
            except:
                pass
            return self.page_size

    (2)让分页功能全局生效settings.py中--这样不用在每个应用的视图中都导入分页了:

    REST_FRAMEWORK = {
     'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
        'PAGE_SIZE':10,
        'DEFAULT_PAGINATION_CLASS':'users.pagination.Pagination'
    }

    若你不希望项目的某个应用不需要分页效果,那你在该应用的视图中viewset类中设置为None即可如下:这样非常灵活

    from .pagination import Pagination
    
    class UserViewset(viewsets.ReadOnlyModelViewSet):
        pagination_class = None

    二.搜索--使用django-filters做高级搜索并全局使用

    参考官网https://django-filter.readthedocs.io/en/master/

    (python36env) [vagrant@CentOS7 devops]$ pip install django-filter

    (2)settings.py中:然后退出pycharm让它把django-filter模块加载起

    INSTALLED_APPS = [
        ...
        'django_filters',
    ]

    REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
    'PAGE_SIZE':10,
    'DEFAULT_PAGINATION_CLASS':'users.pagination.Pagination',
    'DEFAULT_FILTER_BACKENDS': (
    'django_filters.rest_framework.DjangoFilterBackend',
    )
    }

    (3)apps/users/filters.py:

    import django_filters
    from django.contrib.auth import get_user_model
    from django.db.models import Q
    User = get_user_model()
    class UserFilter(django_filters.FilterSet):
        #(3)具体怎么搜索法:这里是按字符串搜索并作用在username字段上,并模糊匹配--不区分大小写
        def search_hostname(self,queryset,name,value):
            return queryset.filter(Q(username__icontains=value)|Q(email__icontains=value))
        class Meta:
            model = User
            #(2)按哪字段搜索
            fields = ["username","email"]

    (4)apps/users/views.py:

    from django.shortcuts import render
    from rest_framework import viewsets
    #from django.contrib.auth.models import User 以后建议换成下面这种写法
    from django.contrib.auth import get_user_model
    from .serializers import UserSerializer
    from rest_framework.pagination import PageNumberPagination
    from .pagination import Pagination
    from  django_filters.rest_framework import DjangoFilterBackend
    from .filters import UserFilter
    
    User = get_user_model()
    class UserViewset(viewsets.ReadOnlyModelViewSet):
        '''
        这个用户资源的viewset会给外面暴露两个接口retrieve和list
        retrieve:
            返回指定用户信息对象--单个对象的字段是在用户序列化类serializers.py中定义
         list:
            返回用户列表--列表的字段的字段是在用户序列化类serializers.py中定义
        '''
        #1.指定queryset
        queryset = User.objects.all()
        #2.指定序列化类
        serializer_class = UserSerializer
        # #(1)用哪个后端做搜索:
        # filter_backends = (DjangoFilterBackend,)
        #(2)按哪个字段搜索:
        filter_fields = ('username',"email")
        #(3)使用哪个filter类
        filter_class = UserFilter

    效果如下:

     别的app应用中也可同样定义如下:servers/filters.py中:并在它自己的视图中调用即可

    import django_filters
    from .models import Server
    from django.db.models import Q
    
    class ServerFilter(django_filters.FilterSet):
        #按主机名搜索
        # hostname = django_filters.CharFilter(method="search_hostname")
        #不光按主机名还可按ip搜索--Q搜索
        def search_hostname(self, queryset, name, value):
            return queryset.filter(Q(hostname__icontains=value)|Q(ip__icontains=value))
    
        class Meta:
            model = Server
            fields = ['hostname','ip']
  • 相关阅读:
    android-基础编程-RecyclerView
    android-基础编程-ListView
    LINUX 日志服务器的搭建
    使用parted进行磁盘分区
    raid磁盘阵列
    LVM逻辑卷管理
    /home 分区迁移试验
    PHP 匹配一个汉字
    xhr dojo load
    ERR: Call to undefined function openssl_random_pseudo_bytes()
  • 原文地址:https://www.cnblogs.com/dbslinux/p/13130187.html
Copyright © 2020-2023  润新知