2020-05-27 Django小结

  1. Web应用
    --- HTTP 请求 --->
    浏览器 服务器
    <--- HTTP 响应 ---

    静态内容:HTML页面、CSS、JavaScript、图像、音视频等 ---> Nginx
    动态内容:需要通过程序自动生成的部分 ---> Python ---> 运行Python程序的服务器

    HTTP(s) ---> 超文本传输协议 ---> 使用了TCP提供的可靠传输服务

    HTTP请求:请求行 / 请求头 / 空行 / 消息体
    HTTP响应:响应行 / 响应头 / 空行 / 消息体

  2. 为什么用Python做后端开发?
    ~ 自动化运维 / 自动化测试 / 数据分析 / AI算法 / DevOps / SRE
    ~ 服务器端应用开发(Web后端开发)
    ---> App/网站的服务端代码编写(数据接口开发)
    ---> 用代码生成网站/App需要的动态内容(数据)
    ---> CGI / WSGI ---> PHP / ASP(C#) / JSP(Java)
    ~ Python也可以为作为服务器端应用开发的编程语言
    ~ 优点:开发效率极高(用很少的代码可以做很多的事情)
    ~ 缺点:执行效率不高(有很多公司更看重开发效率而不是执行效率)
    ~ Python有很多的框架专门用于服务器端应用开发
    ---> 使用框架可以减少重复代码和基础代码的编写
    ---> 程序员只需要专注于核心的业务逻辑代码的编写

  3. 为什么选择Django框架?
    ---> 源于真实的CMS系统的项目
    ---> 生态圈非常繁荣 ---> 大部分功能都有成熟的解决方案

  4. 创建Django项目和实施版本控制
    ~ pip3 install django==2.2.12 -i https://pypi.doubanio.com/simple
    ~ django-admin --version
    ~ django-admin startproject hellodjango
    ~ cd hellodjango

    创建虚拟环境
    ~ 方法一:virtualenv --python=/usr/bin/python3 venv
    ~ 方法二:python3 -m venv venv

    激活虚拟环境
    ~ source venv/bin/activate ---> macOS / Linux
    ~ "venv/Scripts/activate" ---> Windows

    重建项目依赖项:
    ~ 有依赖项清单:pip install -r requirements.txt
    ~ 如果没有依赖项清单:
    - pip install django==2.2.12 mysqlclient django-redis requests
    - pip freeze > requirements.txt

    ~ git init
    ~ 根据需要添加版本控制忽略文件 ---> .gitginore ---> http://gitignore.io/
    ~ git add .
    ~ git commit -m '...'
    ~ Gitee上创建一个空的仓库
    ~ git remote add origin 仓库地址
    ~ git push -u origin master

  5. 创建Django应用
    ~ 一个Django项目中可以包含一个或多个Django应用
    - 方法一:django-admin startapp 应用名
    - 方法二:python manage.py startapp 应用名
    ~ settings.py ---> INSTALLED_APPS ---> 应用名

补充:Django框架使用了MTV架构模式 ---> MVC架构 ---> 数据和显示分离
同一组数据(模型)可以展示为不同的视图(HTML表格、ECharts图表、Excel报表)
同一个视图上也可以加载不同的模型进行渲染
M -----> 模型(数据)-----> M
V -----> 视图(数据的展示,呈现给用户看到的东西)-----> T
C -----> 控制器(连接数据和显示的桥梁,把模型和视图关联起来)-----> V
~ view.py ----> 视图函数 ----> 控制器
~ models.py ----> 模型
~ templates ----> 模板 ----> 视图

  1. 编写视图函数
    ~ views.py ---> 视图函数(接收来自浏览器的请求,给用户以响应)

    def show_index(request: HttpRequest):

     return HttpResponse(content)
    
  2. 配置URL
    ~ 使用视图函数需要配置URL映射(请求的路由) ---> urls.py
    ~ URL(统一资源定位符) ---> 视图函数 ---> path函数

    path('hello/', show_index),
    path('mcode//', get_mobile_code),

    url(r'^mcode/(?P1[3-9]\d{9})/')

    def get_mobile_code(request, tel):
    pass

  3. 前端渲染和后端渲染
    ~ 真正的项目开发中,前端工程师会提供静态页面,如何让静态页面上呈现动态内容???
    ~ 方法一:前端渲染 ---> 在浏览器中完成渲染操作
    前端通过Ajax请求获得后端提供的数据,通过JavaScript代码用数据渲染页面
    ~ 方法二:后端渲染 ---> 在服务器端用Python程序完成
    把前端提供的静态页改造成模板页,把动态内容换成占位符,通过Python程序把动态内容填入模板页

  4. 编写、配置、渲染模板页


      {% for fruit in fruits %}
    • {{ fruit.name }}: {{ fruit.price }}×

    • {% endfor %}

    TEMPLATES = [
    {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [os.path.join(BASE_DIR, 'templates'), ],
    'APP_DIRS': True,
    ...
    },
    ]

    render(request, 'index.html', {...}) ---> HttpResponse

  5. 运行Django项目
    ~ Django自带的测试服务器 ---> 不能用于生产环境
    ~ python manage.py runserver

    Web Server Gateway Interface
    Nginx / Apache --- wsgi ---> 实现了WSGI的服务器
    支持WSGI协议的服务器就可以运行Python项目
    ~ uWSGI / Gunicorn

  6. Django框架中内置了ORM功能
    ~ ORM:对象关系映射 Object-Relational Mapping
    Python程序 ----------------------> 关系型数据库
    对象模型 -----对象持久化到数据库-----> 关系模型
    对象模型 <----从数据库中获取数据------ 关系模型
    class Subject(models.Model):
    ~ AutoField / IntegerField / DecimalField / DateTimeField
    ~ CharField / ImageField / FileField / BooleanField
    ~ OneToOneField / ForeignKey / ManyToManyField
    ~ 新增:Subject(...).save()
    ~ 查询:Subject.objects.all() / Subject.objects.filter() ---> QuerySet
    ~ 查询:Subject.objects.get() / Subject.objects.filter().first() ---> Subject
    ~ 排序:order_by()
    ~ 分页:[:] ---> Paginator ---> get_page() ---> Page
    ~ objects_list / has_prev / has_next / number
    ~ 分组和聚合:annotate() / aggregate()
    ~ 多条件组合筛选:Q对象
    - Q & Q / Q | Q / ~Q
    ~ 更新:subject ---> subject.name = '...' ---> subject.save()
    - F对象:queryset ---> update(字段=F('字段名') + 100)
    ~ 删除:subject ---> subject.delete()

  7. Django模型管理后台
    ~ python manage.py createsuperuser
    ~ 将模型注册到管理后台 ---> admin.py
    admin.site.register(模型, 模型管理类)

    django-jet

  8. 返回JSON格式数据
    JavaScript Object Notation ---> JavaScript创建对象的字面量语法 ---> 数据交换格式
    Python字典 ---> JSON字符串
    ujson ---> ultra json ---> C
    ~ 方法一:ujson.dumps(字典) ---> JSON字符串 ---> HttpResponse ---> application/json
    ~ 方法二:JsonResponse(字典) ---> JSON格式数据

  9. 从请求中获取信息
    HttpRequest
    ~ 获取请求参数:GET / POST / FILES / data
    ~ 获取请求路径: path / get_full_path_info()
    ~ 获取请求方法:method
    ~ 获取请求头:META / COOKIES
    ~ 判断是不是异步请求:is_ajax()
    ~ 获取带签名的cookie:get_signed_cookie()
    HttpResponse
    ~ 响应状态码:status_code
    ~ 响应字符集:charset
    ~ 响应头:
    - response['content-type']
    - response['content-disposition']
    ~ set_cookie() / delete_cookie() / set_signed_cookie()

    用户跟踪:记住用户才能提供更好的更个性化的服务 ---> 浏览器本地存储
    ~ cookie
    ~ localStorage / sessionStorage
    ~ IndexDB

  10. 表单和跨站请求伪造
    CSRF ---> Cross Site Request Forgery ---> 跨站请求伪造/钓鱼网站

    Django框架通过在表单添加随机令牌的方式来解决CSRF问题
    {% csrf_token %}

    如果没有提供有效的随机令牌,Django框架会阻止表单提交,响应状态码403

    @csrf_exempt ---> 视图函数免除CSRF令牌的装饰器

  11. 数据库决不能放用户密码的原始数据 ---> 摘要/签名/指纹
    hashlib ---> md5 / sha1 / sha256
    sha256() ---> update(...) ---> hexdigest()
    彩虹表攻击 ---> 反向查字典破解弱口令
    如果你的网站允许用户使用弱口令,那么一定要通过加盐的方式把弱口令变成强口令再生成摘要
    盐的值只有部署系统的管理员才知道(程序员和DBA都不知道)

  12. 服务器如何保留用户状态 ---> 用户跟踪
    服务器如果能记住用户,记住用户的使用偏好,就能够更好的为用户提供服务
    request.session ---> 保存在服务端的一个类似于字典的对象
    浏览器同时还是用了本地存储技术 ---> cookie ---> 用户身份信息(sessionid)
    ---> HTTP请求头会携带本网站的cookie信息 ---> sessionid --->
    和用户关联的那个session对象 ---> 获取之前保存在session中的数据 ---> 用户跟踪

    浏览器实现本地存储有多种方案:
    ~ cookie(使用起来最简单,浏览器兼容性最好)
    ~ localStorage / sessionStorage
    ~ IndexDB

    request.session['...'] = ...

    python manage.py clearsessions

  13. Django项目接入Redis实现缓存服务
    memcached ---> Redis ---> Django接入Redis
    pip install django-redis

    CACHES = {
    'default': {
    'BACKEND': 'django_redis.cache.RedisCache',
    'LOCATION': 'redis://主机:端口/0',
    'OPTIONS': {
    'CLIENT_CLASS': 'django_redis.client.DefaultClient',
    'PASSWORD': 'Redis口令'
    }
    }
    }

    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
    SESSION_CACHE_ALIAS = 'default'

  14. 导出Excel文件
    Office 2010 ---> Excel 2010 ---> openpyxl
    Office 2003 ---> Excel 2003 ---> xlwt / xlrd

    Workbook ---> sheet ---> sheet['A1'] ---> save()
    BytesIO --- getvalue() ---> bytes ---> HttpResponse
    ~ content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    ~ content-disposition: inline / attachment; filename=...

  15. 生成统计图表
    前端接入ECharts ---> 通过JavaScript实现图表效果渲染
    后端提供JSON数据 ---> JsonResponse

  16. 原生SQL查询
    django.db.transaction.get_connection() ---> Connection对象
    ---> cursor() ---> execute() ---> fetchone() / fetchmany() / fetchall()

  17. 中间件(拦截过滤器)
    def simple_middleware(get_response):

    def middleware(request, *args, **kwargs):
    
        response = get_response(request)
    
        return response
    
    return middleware
    

    Django中间件与之前学过的装饰器在写法和用途上都非常接近,
    通过Django项目配置文件的MIDDLEWARE可以配置使用中间件

  18. 调用三方服务(你自己无法完成的功能)
    ~ SDK集成 --->
    - pip install alipay-python-sdk
    - pip install qiniu
    ~ API调用 ---> URL统一资源定位符 ---> HTTP ---> JSON
    - pip install requests
    request.get(url) / requests.post(url, data={...})

  19. ORM框架调优
    ~ 限制查询字段:only / defer
    ~ 解决1+N查询:select_related / prefetch_related
    ~ Q对象 / F对象

  20. Django-Debug-Toolbar
    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,
    }

    if settings.DEBUG:
    import debug_toolbar
    urlpatterns.insert(0, path('debug/', include(debug_toolbar.urls)))

  1. 日志配置
    ~ 级别:DEBUG < INFO < WARNING < ERROR < CRITICAL

    LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    # 配置日志格式化器
    '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: %(message)s',
    'datefmt': '%Y-%m-%d %H:%M:%S',
    }
    },
    # 配置日志过滤器
    'filters': {
    'require_debug_true': {
    '()': 'django.utils.log.RequireDebugTrue',
    },
    },
    # 配置日志处理器
    'handlers': {
    'console': {
    'class': 'logging.StreamHandler',
    'level': 'DEBUG',
    'filters': ['require_debug_true'],
    'formatter': 'simple',
    },
    'file1': {
    'class': 'logging.handlers.TimedRotatingFileHandler',
    'filename': 'access.log',
    'when': 'W0',
    'backupCount': 12,
    'formatter': 'simple',
    'level': 'INFO',
    },
    'file2': {
    'class': 'logging.handlers.TimedRotatingFileHandler',
    'filename': 'error.log',
    'when': 'D',
    'backupCount': 31,
    'formatter': 'verbose',
    'level': 'WARNING',
    },
    },
    # 配置日志器
    'loggers': {
    'django': {
    'handlers': ['console', 'file1', 'file2'],
    'propagate': True,
    'level': 'DEBUG',
    },
    }
    }

  2. 其他知识点
    ~ DTL:Django模板语法
    模板指令:
    - {% if %} / {% else %} / {% endif %}
    - {% for %} / {% endfor %}
    过滤器:
    - lower / upper / first / last / truncatewords / date/ time
    / length / pluralize / center / ljust / rjust / cut / urlencode
    / default_if_none / filesizeformat / join / slice / slugify

    ~ 路径参数
    - Django 1.x:url(r'mcode/(?P1[3-9]\d{9})')
    - Django 2.x:path('mcode/')

    ~ base64编码:用64个可读文本符号表示任意二进制数据
    base64.b64encode / base64.b64decode

你可能感兴趣的:(2020-05-27 Django小结)