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/<str:tel>/', get_mobile_code),

    url(r'^mcode/(?P<tel>1[3-9]\d{9})/')

    def get_mobile_code(request, tel):
    pass

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

  4. 编写、配置、渲染模板页
    <ul id="fruits">
    {% for fruit in fruits %}
    <li>{{ fruit.name }}: {{ fruit.price }}<a href="">×</a></li>
    {% endfor %}
    </ul>

    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 %}
    <input type="hidden" name="csrfmiddlewaretoken" value="...">
    如果没有提供有效的随机令牌,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/(?P<mobile>1[3-9]\d{9})')
    - Django 2.x:path('mcode/<str:mobile>')

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

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