一.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']
原文地址:https://www.cnblogs.com/dbslinux/p/13130187.html