110.Django REST架构的删除和查询


一.Django REST架构


注意使用这个的时候需要到app中注册:rest_framework
1.请求的过程:实体 ---> 数据 ---> 数据接口 ---> 网络API(HTTP/HTTPS)
2.Django REST框架是一个功能强大且灵活的工具包,用于构建Web API。
安装:

pip install django
pip install djangorestframework


3.用处:REST的用处 经常用在前后端分离的开发模式中,服务端提供API服务,前端用来展示数据,直接通过ajax来沟通。



二.反向生成models

1.从数据库反向迁移到models:
python manage.py inspectdb >comm
on/models.py

要把模型迁移到数据库:
managed = False   变成  true

三.基于类的视图函数

DRF框架中也是支持这两种的:
1.FBV-------基于函数的视图
2.CBV-------基于类的视图
两者的区别在于
(1).FBV更加的灵活
(2).CBV提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承) 可以用不同的函数针对不同的HTTP方法处理,不需要写多个if判断,提高代码可读性。


class EstateView(ListAPIView):
    queryset = Estate.objects.all() #定义查询楼盘的数据
    serializer_class=EstateSerializer(写一个序列化器)
    
#序列化器
class EstateSerializer(serializers.ModelSerializer):

    class Meta:
        model = Estate  #序列化哪个类
        exclude = ('district', 'agents') #不需要序列化
        如果不需要序列化----那么查的时候也不需要查
        Estate.objects.all().defer(需要不查询的字段)
   

以上步骤完成---在映射url:

 path('estates/', EstateView.as_view())
  把上面的EstateView类作为一个视图函数和'estates/'这个url对应。

c.拿单个-------继承RettrieveAPIView

class EstateView(RettrieveAPIView):
    queryset = Estate.objects.all() #定义查询楼盘的数据
    serializer_class=EstateSerializer(写一个序列化器)

以上和拿多个除了继承的类不同,没有其他的区别,有点区别是url的配置:

path('estates/<int:pk>/', EstateView.as_view()),
#其中int:后面的这个pk是默认的规范,必须叫pk.

d.单双一起拿-----python多重继承让类同时继承RettrieveAPIView,ListAPiView。

class EstateView(ListAPIView, RetrieveAPIView):
    queryset = Estate.objects.all().defer('agents')
    serializer_class=EstateSerializer
    def get(self, request, *args, **kwargs):
        if 'pk' in kwargs:
            cls = RetrieveAPIView
        else:
            cls = ListAPIView
        return cls.get(self, request, *args, **kwargs)

但以上的继承是两个父类都是有get方法的:先重写父类的get方法,然后我们做判断如果有pk这个参数,那么一定是拿单个的。就调用RettrieveAPIView这个父类。


e.新增-------在添加一个类继承CreateAPIView

但是注意:如果对同一个类的同一个字段你查看的时候不想查看它,但是新增加的时候确需要看见它,那么你需要写两个序列化器。有两个序列化器的时候你需要重写序列化器的类然后在做判断:

 def get_serializer_class(self):
        if self.request.method in ('POST', 'PUT', 'PATCH'):
            return EstatePostSerializer
        else:
            return EstateSerializer

以上就根据请求的方法做出判断---不同的请求走不同的序列化器。


f.以上的方法过于的繁琐---有拿一个的删除和更新,和拿多个的新增

ListCreateAPIView(拿所有的新增),
RetrieveUpdateDestroyAPIView(拿一个的删除更新)

四.继承ModelViewSet做全套的接口


下面是对一个在view中房屋类型的类进行api接口的步骤:

1.写与模型相关的函数的类:

class HouseTypeViewSet(ModelViewSet):
    queryset = HouseType.objects.all()
    serializer_class = HouseTypeSerializer

2.在应用中注册URL:

配置路由全套房类查询的
需要对url进行注册
router = SimpleRouter()
router.register('housetypes', HouseTypeViewSet)
urlpatterns += router.urls

3.配置url路径:

urlpatterns += router.url
当然上面的也可以直接写入到urlpatterns的这个列表中,我们用的是列表的加法,也是一样的。

五.做缓存的不同方式


1.@cache_page-------这个是装饰器缓存只针对函数

通过设置cache_page可以设置不同地方的缓存,本地,mysql数据库,redis等。

CACHES = {
    # 默认缓存
    'default': {
        # 用什么来做缓存
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': [
            # 可以一主多从
            'redis://118.31.5.162:6379/0',   # 主机用来写
               # 从机用来读(可以有多个)
        ],
        # 区别命名
        'KEY_PREFIX': 'django19062',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',

            # 池化技术(提前连接好,要用时借出去,用完还回来)用空间换时间
            'CONNECTION_POOL_KWARGS': {
                # 最大连接数
                'max_connections': 512,
            },
            'PASSWORD': '361394621tmy',
        }
    },


    # 会话缓存(会话放到缓存的好处:  性能好,不用手动清理,利于水平扩展)
    'session': {
        # 用什么来做缓存
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': [
            # 可以一主多从
            'redis://118.31.5.162:6379/1',   # 主机用来写
            # 'redis://49.233.152.190:6379/0',   # 从机用来读(可以有多个)
        ],
        # 区别命名
        'KEY_PREFIX': 'django19062',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',

            # 池化技术(提前连接好,要用时借出去,用完还回来)用空间换时间
            'CONNECTION_POOL_KWARGS': {
                # 最大连接数
                'max_connections': 1024,
            },
            'PASSWORD': '361394621tmy',
        }
    },
}


# 配置使用缓存来支持用户会话
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# 会话数据放在哪一组缓存中
SESSION_CACHE_ALIAS = 'session'
# 设置会话保存的时长(单位秒)
SESSION_CACHE_AGE = 86400

2.@cache_response-----装饰可以用于类中的函数用于缓存。(第三方的库缓存---需要在setting中配置设置)

REST_FRAMEWORK_EXTENSIONS = {
    'DEFAULT_CACHE_RESPONSE_TIMEOUT': 120,
    'DEFAULT_USE_CACHE': 'default',
    'DEFAULT_OBJECT_CACHE_KEY_FUNC': 'rest_framework_extensions.utils.default_object_cache_key_func',
    'DEFAULT_LIST_CACHE_KEY_FUNC': 'rest_framework_extensions.utils.default_list_cache_key_func',
}

类函数不能用这个。这个缓存是无法拿出新的,一直走缓存的redis.

3.在要做缓存的相应的类种加入CacheRseponseMixn的混入类,这个就是做缓存的相应的类。混入类----混入类会把父类里面的方法替换掉。实现父类本来没有的功能。注意:混入的类必须放在所有的类的前面才有效。但是用了游标分页是无法点击下一页的。用这个做缓存需要将分页设置为默认的分页。

4.把装饰函数的类打到类上面 ---就可以做缓存。

@method_decorator(decorator=cache_page(time=600),name="list")

这个就是把装饰器加到指定的list方法上。

@method_decorator(decorator=cache_page(timeout=600),name="list")
@method_decorator(decorator=cache_page(timeout=600),name="retrieve")
class HouseTypeViewSet(ModelViewSet):
    queryset = HouseType.objects.all()
    serializer_class = HouseTypeSerializer
    pagination_class = None

注意:这种方法有一个缺点,就是你在其他的浏览器再开一次,他会重新加缓存,不会走已有的缓存的键。

六.分页


默认分页---setting里面配置:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 5,
}

不想分页就在相应的类中写:pagination_class=None


游标分页,自定义分页的类:

把分页的类写好----------放入需要分页的类函数中。

分页类:

class EstatePagination(CursorPagination):
    page_size_query_param = 'size'
    max_page_size = 20
    ordering = 'estateid'

七.(补充的知识整理网络响应状态码)

网络响应的状态码.jpg

八. 接口的筛选和排序

(精确筛选)


1.自写选择筛选器:

loupang.png

需要排序:

paixu.png
def get_queryset(self): 
    distid=self. request. GET. get(' district')
    if distid: 
        self. queryset=self. queryset. filter(district=distid)
ordering=self. request. GET. get(' ordering')
    if ordering: 
        self. queryset=self. queryset. order_by(ordering return self. queryset
                                                     

2.使用三方库:django-filter

(1)pip install django-filter

(2).配置setting:apps中加入 "django_filters"

queryset = Estate.objects.all().defer("agents")
   filter_backends = (DjangoFilterBackend,OrderingFilter)
# DjangoFilterBackend类支持数据筛选的类 OrderingFilter是支持排序的类。
   filter_fields=("district",)
# filter_fields  根据什么是做精确的查询
   ordering_fields=("hot","estateid")
#自定义排序的方式
ordering =("price")
#指定默认排序的方式


(模糊筛选)

1.查一个

(1)先自定义模糊的类:

class EstateFilterSet(django_filters.FilterSet):
    intro=django_filters.CharFilter(lookup_expr="contains")
    minhot=django_filters.NumberFilter(field_name="hot",lookup_expr="gte")
    maxhot=django_filters.NumberFilter(field_name="hot",lookup_expr="lte")
  

(2)然后在查询的类中调用这个类:

filterset_class=EstateFilterSet

2.查多个是或者的关系:

在自定义查询类中写入以下的代码:

     foo =django_filters.CharFilter(method="bar")
    def bar(self,queryset,key,value):
        queryset=queryset.filter(Q()| Q)
        return queryset
#     要在几个不同的里面查询,用Q对象表示或者。

3.类的静态方法 查笔记

 @staticmethod
    def filter_by_keyword(queryset, key, value):
        queryset = queryset.filter(Q(name__contains=value) |
                                   Q(intro__s
                                     tartswith=value))
        return queryset

注意:
封装好的类查询都是很方便的,但是比起原生的sql语句性能都是很差的,原生的性能是最好的。


九.查询的限流

1.所有都限流

在setting中配置相关的文件。

在分页的设置中加入以下的代码:

REST_FRAMEWORK = {

    # 按页码分页
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 5,


    # 限流配置
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '5/min',
    },
}

2.单个限流

在查询类中----写出限流的类

throttle_classes =() 或者再后面写自定义的限流的类 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容