Django-接口
restful
序列化
序列化:对象 -> 可存储传输的数据 json–dumps(obj,ensure_ascii=True中文编码,indent=None缩进显示)
反序列化:可存储传输的数据 -> 对象
序列化-json
| 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 |
|---|
| 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
|
| 视图层 |
|---|
| 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
|
| 路由 |
|---|
| 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
分页 过滤 搜索
| 分页类 |
|---|
| 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')
|
| 搜索 |
|---|
| 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'
2、REST_FRAMEWORK 添加 "DEFAULE_AUTHENTICATION_CLASSES": ('rest_framework.authentication.TokenAuthentication',),
# 或者在视图添加 authentication_classes = (TokenAuthentication,)
3、数据库迁移 py manage.py makemigrations ,migrate
4、urls.py 添加路由 path('api',obtain_auth_token),
5、在要求中视图声明 permission_classes = (IsAuthenticated,)
此时访问提示无权限
浏览器请求头添加 token即可
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
|
| REST_FRAMEWORK |
|---|
| 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’}