一.分页:
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']