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 =() 或者再后面写自定义的限流的类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值