跳转至

Django-接口

restful

序列化

序列化:对象 -> 可存储传输的数据 json–dumps(obj,ensure_ascii=True中文编码,indent=None缩进显示)
反序列化:可存储传输的数据 -> 对象

序列化-json

1
2
3
4
5
def api_json(r):
    objs = logtable.objects.all()[:30]
    listobj = list(objs.values("host","message"))
    js = json.dumps(listobj,ensure_ascii=False,indent=100)
    return HttpResponse(js)

DFR

装配

安装框架

pip install djangorestframework

配置
setting.py 的apps 中 添加 ‘rest_framework’,

使用

Serializer 和 ModelSerializer 两种序列化,

创建mode
1
2
3
4
5
6
7
8
9
class logtable(models.Model):
    time_add_record = models.DateTimeField('实际接收时间', max_length=1024, null=True, blank=True)
    time_log = models.DateTimeField('日志产生时间', max_length=1024, null=True, blank=True)
    host = models.CharField('主机来源', max_length=1024, null=True, blank=True)
    appname = models.CharField('进程名称', max_length=1024, null=True, blank=True)
    apppid = models.IntegerField('进程pid', null=True, blank=True)
    level = models.CharField('日志等级', max_length=1024, null=True, blank=True)
    component = models.CharField('组件', max_length=1024, null=True, blank=True)
    message = models.CharField('内容', max_length=1024, null=True, blank=True)
当涉及到外键、多对多等情况时,可以使用多个序列化嵌套完成序列化
序列化类
from rest_framework import serializers
from .models import *

class Serial_logtable(serializers.Serializer):
    # 手工序列化,在字段较多,环境复杂时使用
    host = serializers.CharField(required=True)
    message = serializers.CharField()

class Serial_matelogtable(serializers.ModelSerializer):
    # 继承不同的类,自动序列化全部序列
    class Meta:
        model  = logtable
        fields = "__all__"
    def create(self, validated_data):
        print(type(validated_data))
        return logtable.objects.create(**validated_data)
    def update(self, instance, validated_data):
        instance.time_log = validated_data.get("time_log")
        instance.save()
        return instance

视图层
1
2
3
4
5
6
7
8
class logViews(APIView):
    def get(self,request,*args,**kwargs):
        objss = logtable.objects.all()[:30]
        # objs = Queryser 则many = True
        # objs = 模型类 many = False
        js = Serial_logtable(objss,many=True).data # 返回手动序列化的内容
        js = Serial_matelogtable(objss,many=True).data # 返回自动序列化的内容
        return  Response(js) # from rest_framework.response import Response
路由
1
2
3
urlpatterns = [
    re_path('^ddd$', logViews.as_view()),
]

ListCreateAPIView 简化写法

在上面的方法中,视图层可以继承 ListCreateAPIView 进而简单书写

ListCreateAPIView 简化后的视图层
from rest_framework import status,mixins,generics
class genview(generics.ListCreateAPIView):

    queryset = logtable.objects.all()[:30]
    serializer_class = Serial_matelogtable

ListCreateAPIView 实现了get post 两种方法获取创建


generics中主要类的说明

# Concrete view for retrieving, updating or deleting a model instance.(get put patch delete )方法
generics.RetrieveUpdateDestroyAPIView

# 提供了查询,主键,搜索,分页等功能(重点)
generics.GenericAPIView

视图集

在一个类中完成增删改查,可以吧 GenericViewSet

分页 过滤 搜索

分页类
1
2
3
4
5
class cutpage(PageNumberPagination):
    page_size = 5  # 每页显示记录数,前端没有传入page_num,则默认显示此参数
    page_size_query_param = 'page_num'  # 前端传入每页显示条数
    page_query_param = "page"  # 前端传入第几页
    max_page_size = 10  # 后端控制每页显示最大记录数
过滤器的两种写法
 pip install django-filter
INSTALLED_APPS = [
    ...
    'django_filters',
]
----
REST_FRAMEWORK = {
   # 过滤器默认后端
    'DEFAULT_FILTER_BACKENDS': (
           'django_filters.rest_framework.DjangoFilterBackend',), # 第二种指定过滤器后端模板的方式,
}
-----
class ArticleFilter(django_filters.FilterSet):
    # 两种写法
    q = django_filters.CharFilter(field_name='host', lookup_expr='icontains')
    class Meta:
        model = logtable
        fields = ('level', 'message')
搜索
1
2
3
4
5
class cutpage(PageNumberPagination):
    page_size = 5  # 每页显示记录数,前端没有传入page_num,则默认显示此参数
    page_size_query_param = 'page_num'  # 前端传入每页显示条数
    page_query_param = "page"  # 前端传入第几页
    max_page_size = 10  # 后端控制每页显示最大记录数
搜索、排序、过滤、分页归总
class ProductViewSet(ModelViewSet):
    queryset = logtable.objects.all().order_by('id') # 排序后分页不会告警
    serializer_class = Serial_matelogtable # 序列化器
    pagination_class = cutpage # 分页
    filterset_class = ArticleFilter # 过滤器
    filter_backends = (DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter)
    # 过滤:指定过滤器后端的方式 1 ,也可以在setting.py 中指定
    # 搜索:rest_framework.filters.SearchFilter
    # 排序:
    search_fields=("component","message") # 要搜索的字段
    ordering_fields = ("time_log","id")
    def get_queryset(self):
        return logtable.objects.all()

权限认证

环境准备
1添加app 'rest_framework.authtoken'
2REST_FRAMEWORK 添加 "DEFAULE_AUTHENTICATION_CLASSES": ('rest_framework.authentication.TokenAuthentication',), 
    # 或者在视图添加 authentication_classes = (TokenAuthentication,)
3数据库迁移 py manage.py makemigrations migrate
4urls.py 添加路由 path('api',obtain_auth_token),
5在要求中视图声明 permission_classes = (IsAuthenticated,)

此时访问提示无权限
浏览器请求头添加 token即可
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
REST_FRAMEWORK
1
2
3
4
5
6
7
REST_FRAMEWORK = {
    # 过滤器默认后端
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',),
    "DEFAULE_AUTHENTICATION_CLASSES": ('rest_framework.authentication.TokenAuthentication',),

}

as_view说明 as_view({‘get’: ‘list’,’post’: ‘create’, ‘put’: ‘update’, ‘delete’: ‘destroy’}