01-11第十周周报

本周是第十周,本周学习了django框架前后端分离相关知识点,REST框架,网络API接口,以及性能调试,以下是知识点回顾与整理:

1.11本周总结

  1. 版本控制补充 - 回退

    - git reset --hard versionid / head^

    - git reflog 记录

  2. django日志配置 - settings.py

    日志级别:DEBUG < INFO < WARNING < ERROR < CRITICAL

    ELK - ElasticSearch Logstash Kibana - 日志处理平台

    # settings.py,以下配置为日志debug级别打印至控制台
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db': {
                'handlers': ['console', ],
                'level': 'DEBUG',
            },
        },
    }
    

  3. django-debug-toolbar - django调试工具

    debug-debug-toolbar可查看数据请求的时长、数据库查询语句等

    配置:settings.py与urls.py

    # 首先安装第三方库:pip install django-debug-toolbar
    # settings.py
    INSTALLED_APPS = [
        ...
        'debug_toolbar',
    ]
    MIDDLEWARE = [
        'debug_toolbar.middleware.DebugToolbarMiddleware',
    ]
    DEBUG_TOOLBAR_CONFIG = {
        # 引入jQuery库
        'JQUERY_URL': 'https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js',
        # 工具栏是否折叠
        'SHOW_COLLAPSED': True,
        # 是否显示工具栏
        'SHOW_TOOLBAR_CALLBACK': lambda x: True,
    }
    # urls.py
    from django.conf import settings
    from django.urls import include
    if settings.DEBUG:
        import debug_toolbar
        urlpatterns.insert(0, path('__debug__/', include(debug_toolbar.urls)))
    
  4. 性能优化之一,数据库1+N查询问题,是指只需只需用SQL语句查询一次即可出结果,却重复查询多次

    方法:利用django的连表查询

    ​ - 一对多:select_related()

    ​ - 多对多:prefetch_related()

  5. django项目前后端分离开发

    - 服务器完成核心业务返回json等数据,客服端处理渲染数据与页面

    - 优点:

    • 提升开发效率
    • 增强代码可维护性
    • 支持多终端和服务器结构
  6. API - Application Programming Interface 应用程序编程接口

    网络API - 通过http/https请求请求一个url获得json数据

    API接口应围绕实体设计,而不是围绕业务设计,否则后期更改会增加工作量与复杂度

    实体 -- 数据 -- 数据接口 -- 网络API(基于http/https)

    REST架构 - RESTful API -- 无状态、幂等性

    ​ - 幂等性:一次货多次请求某一个资源对于资源本身具有同样的结果

    ​ REST - REpresentational State Transfer - 表现层状态转移

    ​ rest可以更好的支持水平扩展 - 单机结构 --> 多机结构(分布式集群)

    http -- 无连接无状态协议

    url -- universal resource locator 统一资源定位符,根据rest架构url设计应使用名词

    get -- 查看

    post -- 新增

    put -- 全更新

    patch -- 补丁似的更新

    delete -- 删除

  7. 具体网络API接口项目如下,以房源信息获取为例:

    - 首先对rest框架进行安装配置

    # rest框架的安装 - pip install djangorestframework
    # settings.py 
    INSTALLED_APPS = [
     ...
        'rest_framework',
    ]
    

    - 其次,序列化房源信息

    ​ fields表示需要获取的数据,'__all__'表示获取全部数据,exclude表示排除的数据

    # 序列化器,在app文件夹下创建一个serializers.py存放序列化内容,对需要的数据进行序列化
    # serializers.py
    from rest_framework import serializers
    from common.models import District, Estate, Agent, HouseType, HouseInfo
    
    class HouseInfoSerializer(serializers.ModelSerializer):
        class Meta:
            model = HouseInfo
            fields = '__all__'
            # exclude = ('houseid',)
    

    - CBV视图创建

    # view.py
    from rest_framework.viewsets import ReadOnlyModelViewSet
    from common.models import HouseInfo
    from common.serializers import HouseInfoSerializer
    
    # CBV基于类的视图创建
    class HouseInfoViewSet(ReadOnlyModelViewSet):
        queryset = HouseInfo.objects.all().select_related('type', 'district', 'estate', 'agent').prefetch_related('tags').order_by('-pubdate')
        serializer_class = HouseInfoSerializer
    

    - urls.py配置,在app文件夹内 创建一个新的urls.py配置文件,作为单独的配置

    # urls.py
    from django.urls import path
    from rest_framework.routers import SimpleRouter
    from common.views import HouseInfoViewSet
    
    # 创建一个房源信息的路由
    router = SimpleRouter()
    router.register('houseinfo', HouseInfoViewSet)
    urlpatterns += router.urls
    

    这时房源的全部信息API接口已经完成,进入http://127.0.0.1:8000/api/houseinfo/ 可获取房源的全部信息

  8. 设置全局分页查看房源信息,并且限制查询次数每分钟5次

    # DRF配置文件
    REST_FRAMEWORK = {
        # 按页码分页
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 5,  # 每页最大显示5条数据
        # 限流配置
        'DEFAULT_THROTTLE_CLASSES': (
            'rest_framework.throttling.AnonRateThrottle',
        ),
        'DEFAULT_THROTTLE_RATES': {
            'anon': '5/min',  # 一分钟访问5次
        },
    }
    
  9. 设置redis缓存,对部分长期不变的信息进行缓存,可减轻数据库负担,提高查询速度,从而提高用户体验

    # settings.py
    # rest缓存配置
    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缓存配置
    CACHES = {
        'default': {
            'BACKEND': 'django_redis.cache.RedisCache',
            'LOCATION': [
                'redis://ip address/0',
            ],
            'KEY_PREFIX': 'projcet_name',
            'OPTIONS': {
                'CLIENT_CLASS': 'django_redis.client.DefaultClient',
                'CONNECTION_POOL_KWARGS': {
                    'max_connections': 512,
                },
                'PASSWORD': 'your password',
            }
        },
    }
    

    - 在app文件夹下创建一个utils.py的文件,用于存放app的功能函数等

    # utils.py
    # 对redis存储的缓存前缀进行修改
    import re
    PATTERN = re.compile(r'(\.[0-9a-f]{32})')
    
    
    def make_key(key, key_prefix, version):
        items = PATTERN.findall(key)[1:]
        for item in items:
            key = key.replace(item, '')
        return '%s:%s:%s' % (key_prefix, version, key)
    

    - 在view.py中添加装饰器,对需要缓存的数据添加装饰器

    # view.py
    
    class HouseInfoViewSet(CacheResponseMixin,ModelViewSet):
        ...
    
  10. 添加筛选器,对关键字进行筛选,或者对价格进行排序,筛选价格区间等等

    # utils.py
    # 自定义filterset过滤器筛选功能
    class HouseInfoFilterSet(django_filters.FilterSet):
        """自定义FilterSet过滤"""
        minprice = django_filters.NumberFilter(field_name='price', lookup_expr='gte')
        maxprice = django_filters.NumberFilter(field_name='price', lookup_expr='lte')
        keyword = django_filters.CharFilter(method='filter_by_keyword')
    
        @staticmethod
        def filter_by_keyword(queryset, key, value):
            queryset = queryset.filter(Q(title__contains=value) |
                                       Q(detail__contains=value) | Q(street__contains=value))
            return queryset
    

    - 其次在views.py文件,房源信息视图类中添加如下内容

    # views.py
    from django_filters.rest_framework import DjangoFilterBackend
    from rest_framework.filters import OrderingFilter
    from common.utils import HouseInfoFilterSet
    
    class HouseInfoViewSet(ModelViewSet):
        ...
        filter_backends = (DjangoFilterBackend, OrderingFilter)
        filterset_class = HouseInfoFilterSet
        ordering_fields = ('price', 'area', 'floor')  # 排序内容
    

你可能感兴趣的:(01-11第十周周报)