美文网首页
Django 温故

Django 温故

作者: 垃圾桶边的狗 | 来源:发表于2018-12-24 02:31 被阅读0次

    HTTP Objects

    HttpRequest

    • ⾃自身属性

      • request.path ->/foo/bar/

      • request.method -> POST , GET

      • 类字典属性
        • request.GET
        • request.POST
        • request.COOKIES
        • request.FILES -> {name1: file1, name2: file2, ...}
        • request.META['REMOTE_ADDR']
        • request.META['HTTP_USER_AGENT']
      • 中间件属性
        • request.session
        • request.user
      • 方法
        • request.get_full_path() -> /foo/bar/?a=123
        • request.get_signed_cookie(key)
    • HttpResponse

      • 属性
        • response.status_code
        • response.content
      • 方法
        • response.set_cookie(key, value, max_age=None)
      • JsonResponse
        • response = JsonResponse({'a': 12, 'b': 'xyz'})

    Django 中间件

    • ⾯面向切⽚片编程
    • 最简单的中间件
     
    def simple_middleware(get_response):
        # do_something_for_init()
        def middleware(request):
            # do_something_before_views(request)
            response = get_response(request) # views 函数在这⾥里里执⾏行行 # do_something_after_views(response)
            return response
        return middleware
    
    • 中间件类
     
    class MyMiddleware:
        def __init__(self, get_response):
            self.get_response = get_response
        def __call__(self, request):
            # do_something_before_views(request)
            response = self.get_response(request)
            # do_something_after_views(response)
            return response
        def process_view(self, request, view_func, view_args,view_kwargs):
            response = view_func(*view_args, **view_kwargs)
            return response
    
    • Django-1.10 以前的中间件
     
    from django.utils.deprecation import MiddlewareMixin
    class MyMiddleware(MiddlewareMixin):
        def process_request(self, request):
            pass
        def process_view(self, request, view_func, view_args,view_kwargs):
            pass
        def process_response(self, request, response):
            return response
    
    • 执⾏行行顺序
      • process_request, process_view 从上往下执⾏
      • process_response 从下往上执⾏
    • 内置中间件排序

    Form 表单

    • 核心功能:数据验证
    • form的method只能是POST或GET
    • method=GET时,表单提交的参数会出现在URL里
    • 属性和方法
      • form.is_valid()
      • form.has_changed()
      • form.clean_<field()>
    • Form的定义和使用

     
    from django.forms import Form
    from django.forms import IntegerField, CharField, DateField,
    ChoiceField
    class TestForm(Form):
        TAGS = (
            ('py', 'python'),
            ('ln', 'linux'),
            ('dj', 'django'),
        )
        fid = IntegerField()
        name = CharField(max_length=10)
        tag = ChoiceField(choices=TAGS)
        date = DateField()
    data = {'fid': 'abc123', 'name': '1234567890', 'tag': 'dj', 'date':
    '2017-12-17'}
    form = TestForm(data)
    print(form.is_valid())
    print(form.cleaned_data) # cleaned_data 属性是 is_valid 函数执⾏行行时动态添 加的
    print(form.errors)
    
    • ModelForm

     
    class UserForm(ModelForm):
        class Meta:
            model = User
            fields = ['name', 'birth']
    

    模板

    • base.html 模板推荐布局

    !sdfds.png](https://img.haomeiwen.com/i12529562/a0929192276e348e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

     
    <!DOCTYPE html>
    <html>
        <head>
            <title>{{title}}</title>
            <link rel="stylesheet" type="text/css"
    href="/static/css/style.css">
            {% block "ext_css" %}{% endblock %}
        </head>
        <body>
            <!-- {% block "navbar" %}{% endblock %} -->
            {% block "sidebar" %}{% endblock %}
            {% block "content" %}{% endblock %}
            <!-- {% block "footbar" %}{% endblock %} -->
            <script
    src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
            {% block "ext_js" %}{% endblock %}
        </body>
    </html>
    
    <form>
        {% csrf_token %}
        <input type="text" name="x" value="123">
    </form>
    
    • for...endfor 中的变量量

      • forloop.counter 从 1 开始计数
        -forloop.counter0从 0 开始计数
      • forloop.revcounter逆序计数到 1
      • forloop.revcounter0逆序计数到 0
      • forloop.first 是否是循环中的第⼀一个
      • forloop.last 是否是循环中的最后⼀一个
      • forloop.parentloop⽤用于引⽤用上级循环中的变量量, 如{{forloop.parentloop.counter }}
    • empty 子句句

     
    {% for x in lst %}
        <div>...</div>
    {% empty %}
        <div>Sorry</div>
    {% endfor %}
    
    • load: 加载⾃自定义 Tag {% load foo.bar %}
    • url: 根据 url name 替换 {% url 'your-url-name'v1 v2 %}
    • static
     {% load static %}
    <img src="{% static "img/smile.jpg" %}">
    
     {% load static %}
    <img src="{% get_static_prefix %}img/smile.jpg">
    

    内建的 filter

    • 什什么是 ORM

    • CURD (Create/Update/Retrieve/Delete)

    对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。那么,到底如何实现持久化呢?一种简单的方案是采用硬编码方式,为每一种可能的数据库访问操作提供单独的方法。
    这种方案存在以下不足:
    1.持久化层缺乏弹性。一旦出现业务需求的变更,就必须修改持久化层的接口
    2.持久化层同时与域模型与关系数据库模型绑定,不管域模型还是关系数据库模型发生变化,毒药修改持久化曾的相关程序代码,增加了软件的维护难度。

        ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。Java典型的ORM中间件有:Hibernate,ibatis,speedframework。 
        ORM的方法论基于三个核心原则: 
    

    · 简单:以最基本的形式建模数据。
      · 传达性:数据库结构被任何人都能理解的语言文档化。
      · 精确性:基于数据模型创建正确标准化了的结构。

    • Field

    • 选项

    • null 针对数据库, 允许数据库该字段为 Null
    • blank针对 Model 本身, 允许传⼊入字段为空. blank 为 True 时, 对数据库来说, 该字段依然 为必填项
    • default尽量量使⽤用 default, 少⽤用 null 和 blank
    • primary_key ⾮非必要时不不要设置, ⽤用默认 id, 保持条⽬目⾃自增、有序、唯⼀一
    • unique
    • db_index(True | False)
    • max_length
    • auto_now每次 save 时,更更新为当前时间
    • auto_now_add只记录创建时的时间, 保存时不不更更新
    • QuerySet

      • 方法

        • 创建:create() / get_or_create() / update_or_create() / bulk_create()
        • 条件过滤和排除:filter() / exclude()
        • 只加载需要的字段: only() / defer()
        • order_by() / count() / exists() latest() / earliest()
        • first() / last()
      • 查找条件

        • filter(id__in=[123, 555, 231])

        • filter(id__range=[123, 456])

        • filter(name__contains='123')

        • filter(name__regex='^\w+\d+')

        • filter(id__lte=123)

        • gt / gte / lt / lte

    • 其他 ORM

    • 主键和外键约束

      • 内部系统、传统企业级应⽤可以使⽤ (需要数据量可控,数据库服务器器数量可控)
      • 互联⽹行业不不建议使⽤用
        • 性能缺陷
        • 不不能⽤用于分布式环境
        • 不不容易易做到数据解耦

    Cache

    • 默认缓存: from django.core.cache import cache

    • BACKEND: DatabaseCache / MemcachedCache / LocMemCache

    • LOCATION: IP:Port 绑定, 只有⼀一个时配制成字符串串链接, 有多台时配制为列列表

    • 使⽤用 Redis 做缓存

     
    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/1",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "PICKLE_VERSION": -1,
            }
          }
    }
    
    • 基本方法

      •     cache.set(key, value, timeout=None)
        
      •     cache.get(key, default=None)
        
      •     cache.delete(key)
        
      •     cache.incr('num')
        
      •     cache.decr('num')
        
      •     cache.get_or_set(key, default, timeout=None)
        
      •     cache.set_many({'a': 1, 'b': 2, 'c': 3})
        
      •     cache.get_many(['a', 'b', 'c'])
        
    • 全站缓存中间件: django.middleware.cache.UpdateCacheMiddleware

      • 前置中间件
      • 缓存期限:CACHE_MIDDLEWARE_SECONDS
      • ⻚页⾯面缓存装饰器器:from django.views.decorators.cache import cache_page
      • 属性缓存装饰器器: from django.utils.functional import cached_property
      • pickle
        •      data = dumps(obj, -1)
          
        •      obj = loads(data)
          

    Cookie 和 Session

    • 产生过程

        1. 浏览器器 发起请求访问服务器器
        1. 服务器器 为 浏览器器 创建 Session 对象, 其中包含⼀一个全局唯⼀一的 ID —— session_id
        1. 服务器器 将 session_id 写⼊入 response 的 Cookie 中, 传回 浏览器器
        1. 浏览器器 取出 session_id, 并将其存⼊入 Cookie
        1. 后续每次请求 session_id 会随 Cookie ⼀一同传到 服务器器
        1. 服务器器 取出 session_id 并找出⽤用户之前存储的状态信息
    • Cookie:response.set_cookie(key, value, max_age=None)

    • Session 配置

    1. 开启 Session 中间件: django.contrib.sessions.middleware.SessionMiddleware2. 配置缓存
    2. 配置 Session 引擎: SESSION_ENGINE = "django.contrib.sessions.backends.cache"
    • 可选项

      • SESSION_COOKIE_AGE 缓存时间, 默认 2 周
      • SESSION_COOKIE_NAME Session名, 默认 'sessionid'
      • SESSION_EXPIRE_AT_BROWSER_CLOSE 浏览器关 - 闭⻚页⾯面时, Session 是否设为过期
      • SESSION_SAVE_EVERY_REQUEST 每次请求时, 是否强制保存⼀次 Session
    • 用法

      • request.session.session_key 查看 session_id
      • request.session.modified session 是否发⽣生过修改
      • request.session['uid'] = 1234 当 session 发⽣生更更改时会⾃自动保存
      • request.session.get('uid') 取值
      • request.session.save() ⼿手动保存

    Logging

    • ⽇日志级别

      • DEBUG
      • INFO
      • WARNING
      • ERROR
      • FATAL
    • 使用

    • logger.debug('xxxxxxxx')
    • logger.info('xxxxxxxx')
    • logger.warning('xxxxxxxx')
    • logger.error('xxxxxxxx')
    • logger.fatal('xxxxxxxx')
    • 查找、分析

      • tail
      • head
      • less
      • awk
      • grep

    配置

     
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'simple': {
                'format': '%(asctime)s %(module)s.%(funcName)s: %(message)s',
                'datefmt': '%Y-%m-%d %H:%M:%S',
            },
            'verbose': { 
                'format': '%(asctime)s %(levelname)s [%(process)d-%(threadName)s] '
                          '%(module)s.%(funcName)s line %(lineno)d: %
                'datefmt': '%Y-%m-%d %H:%M:%S',
        'handlers': {
            'inf': {
    'class': 'logging.handlers.TimedRotatingFileHandler', 'filename': 'info.log',
    'when': 'W0', # 每周⼀一切割⽇日志
    'backupCount': 5,
                'formatter': 'simple',
                'level': 'INFO',
            },
    'err': {
    'class': 'logging.handlers.TimedRotatingFileHandler', 'filename': 'error.log',
    'when': 'D', # 每天切割⽇日志
    'backupCount': 30,
    'formatter': 'verbose',
    'level': 'WARNING',
    } },
    
        'loggers': {
            'inf': {
                'handlers': ['inf'],
                'level': 'DEBUG',
                'propagate': True,
    }, 'err': {
    (message)s',
            }
    },
    } }
    }
    

    Django 的性能

    • Django ⾃自身优化

      • 充分之⽤用缓存

      • 惰性求值和迭代器器
      • 尽量量使⽤用 defer() 和 only() 查找
      • 尽量量使⽤用 count() 和 exists()
      • 模板中 {% block %} 性能优于 {% include %}
      • 开启模板缓存
      • 不要使⽤用外键!不不要使⽤用外键!不不要使⽤用外键!
    • 其他优化

      • I/O 密集型: 异步化
        • 请求异步化
        • 数据操作异步化
        • gevent, asyncio, aiopg, aiohttp, tornado
      • 计算密集型
        • 耗时操作⽤用 Celery 等⼯工具异步完成
      • 分库分表
        • 取余、哈希
        • 范围
        • ⼀致性哈希
      • 索引优化
      • 慢查询优化
      • Gunicorn 开启多进程模式利利⽤多核
      • PyPy
      • Cython

    相关文章

      网友评论

          本文标题:Django 温故

          本文链接:https://www.haomeiwen.com/subject/zltakqtx.html