python_Django
阅读原文时间:2023年07月11日阅读:1

1、Python用具 - pip
    1、作用:
        Python的软件包管理器,有一些python包被集成到了pip中。只要被集成到pip中的包,都允许通过pip直接安装
    2、安装 pip
        sudo apt install python-pip(python2)
        sudo apt install python3-pip(python3)
    3、使用pip/ pip3
        1、安装/下载/更新/删除 python包
            1、安装python包(下载并安装)
                sudo pip3 install SomePackage
                sudo pip3 install PyMySQL==0.7.11(如果不写版本号默认为最新的版本)
            2、下载python包(值下载不安装)
                sudo pip3 download SomePackage
            3、删除python包
                sudo pip3 uninstall SomePackage
            4、更新(升级)python包
                sudo pip3 upgrade SomePackage
        2、查看当前环境中所安装的包
            pip3 list
        3、搜索
            pip3 search SomePackage
        4、展示
            pip3 show SomePackage
        5、记录现有环境的python包
            1、pip3 freeze > requirements.txt
                将当前python环境中所安装的内容打包成一个txt文件
            2、pip3 install -r requirements.txt
                允许在当前系统下,逐一安装requirements.txt中所有列出的内容
2、Python工具 - VirtualEnv
    1、什么是VirtualEnv - 虚拟环境
        virtualEnv是python中的虚拟环境,在做python应用开发时,如果不想在大的python环境中安装各种各样的包的话,则可以虚拟出一个python环境,可以让虚拟环境专门为某一应用而存在。允许在虚拟环境中安装各种包且不影响大的python环境
    2、安装VirtualEnv
        sudo pip3 install virtualenv
    3、创建 和 使用 虚拟环境
        1、准备工作
            mkdir my_env
            cd my_env
        2、创建虚拟环境
            virtualenv 虚拟环境名称
            示例:virtualenv default
            创建指定版本的虚拟环境
            virtualenv -p /usr/bin.python2.7 名称
            virtualenv -p /usr/bin.python3.6 名称    
        3、启动虚拟环境
            注意:不能在bin目录中启动虚拟环境(根目录下的bin目录)
            source bin/activate
        4、退出虚拟环境
            deactivate
        5、删除虚拟环境
            rm 虚拟环境目录 -rf
        注意:在虚拟环境中使用pip安装和卸载内容时,不要使用sudo进行授权,如果使用则操作的是大环境
    4、虚拟环境管理工具 - VirtualenvWrapper
        1、作用
            第三方的管理工具,能够快速,高效且方便的管理虚拟环境
        2、安装虚拟环境管理工具
            sudo pip3 install virtualenvwrapper
        3、配置virtualenvwrapper
            在~(家目录)目录下,有一个终端管理文件 .bashrc(在~目录下,输入ll查看)
            配置.bashhrc,以便在启动终端时,就自动启动虚拟环境管理工具
            修改.bashrc: sudo vi .bashrc
            在.bashrc 最底部增加一下内容
            1、export WORKON_HOME=~/my_env:
                将~/my_env 作为虚拟环境的管理目录,所有使用virtualenvwrapper创建的虚拟环境都默认保存于此
            2、如果系统中包含多个python执行环境的话,则添加一下内容
                export VIRTUALENVWRPPER_PYTHON=/usr/bin/python3
            3、source /usr/local/bin/virtualenvwrapper.sh:默认启动刮管理工具
            4、在~目录下,执行一遍.bashrc
                source .bashrc
        4、使用虚拟环境管理工具
            1、创建并进入虚拟环境管理工具
                1、mkvirtualenv 虚拟环境名称
                2、mkvirtualenv --python=/usr/bin/python2.7 env2.7
            2、查看当前所维护的所有虚拟环境
                workon
            3、切换虚拟环境
                workon 虚拟环境名称
            4、退出虚拟环境
                deactivate
            5、删除虚拟环境
                rmvirtualenv 虚拟环境名称
3、WEB 与 服务器
    1、WEB:表示用户可以浏览的网页(HTML,CSS,JS)
    2、服务器:专门给用户提供服务的一台机器
        1、硬件 与 软件
            硬件范畴:一台主机
            软件范畴:一个能够接收用户请求并给出响应的程序

    1、APACHE

    2、TOMCAT

    3、IIS(Internet Information Service)

    4、Nginx

2、作用:
            1、存储WEB上的信息(网页,图片,音视频,css,js)
            2、能够处理用户的请求(request)并给出响应(response)
            3、能够执行服务器端程序:如查询数据库
        3、WEB与服务器的关系

     WEB需要放在服务器上才能够被用户访问

运行在服务器端的程序,可以由不同的语言来编写
                Java语言-->JSP
                C#语言-->ASP>NET
                PHP语言-->php
                Python语言-->Django
        4、网站请求的全过程
            1、用户:输入域名,通过域名解析(DNS)器得到IP地址
            2、向服务器发送http(开80端口)/https(开440端口)请求
            3、传输层TCP协议,经过网络传输和路由解析
            4、WEB服务器接收HTTP请求
            5、服务器处理请求内容,并进行必要的数据交换(我们需要做的事情)
            6、将响应的内容发回给浏览器(响应)
            7、浏览器解析HTML
            8、显示解析好的内容

4、框架
    1、什么是框架
        框架是一个为了解决某些开放性问题而存在的一种结构。框架本身提供了最基本的功能,我们只需在这些基本功能上构建自己的操作即可。
    2、框架的优点
        1、快速开发 - 基本功能已经提供好了
        2、可以解决大部分问题
        3、bug少,稳定性较高
    3、框架的分类
        1、前端框架
            处理前端内容(HTML,CSS,JS)
        2、后端框架
            处理服务器程序的
            Spring -Java
        3、全栈框架
            包含WEB整体的解决方案,包括开发框架,运行环境
            Rails(Ruby)
            Django(Python)
        4、Python的WEB框架
            1、Django:重量级的Python Web框架
            2、Tornado:异步框架
            3、Flask:轻量级框架,直接引入模块即可使用
            4、Webpy:轻量级框架
            5、Web2py:全栈框架,webpy的加强版

1、设计模式 与 框架模式
    1、设计模式
        设计模式,是一套被反复使用,多数人知晓并经过分类的代码设计经验的总结,是为了解决一些通用性问题的
        目的:重用代码并保证代码的可靠性
        官方认证的设计模式有23中:单列模式,抽象工厂模式,观察者模式等 《大话设计模式》
    2、框架模式
        代码的重用,框架模式是解决如何设计程序框架的代码,在框架模式中会包含多种的设计模式
        如:MVC,MTV,MVVM,ORM,…
        1、MVC
            M:Models,模型层,
                在程序中主要处理数据,负责在数据库中对数据进行存取操作(CRUD)
            V:Views,视图层
                应用程序中处理显示的部分内容(HTMl,JSP)
            C:Controllers,控制器层
                处理用户交互的部分,通常负责从模型中取出数据,再进行业务的处理,最后将数据给视图,并将视图给客户端

2、MTV
            M:Models 模型层,

     模型层,负责数据库建模以及CRUD的操作
            T:Templates 模板层
                用于处理用户显示的部分内容,如:html
            V:Views 视图层
                处理用户交互部分,从模型中获取数据,再将数据给模板,在显示给用户

2、Django框架
    1、什么是Django
        是一个开源框架,2005年发布,采用python语言开发的。早期Django是做新闻和内容管理的网站的,提供了非常强大的后台管理系统,采用的是MTV框架模式
    2、Gjango的优缺点
        1、优点
            1、开源框架,有完美的文档支持
            2、解决方案比较完整,内部功能也比较多
            3、提供完整的路由系统,优雅的URL解析方式
            4、自助式的后台管理
        2、缺点
            1、耦合度偏高
    3、Django的安装
        1、Linux中的安装
            1、查看已安装的Django
                1、进入到虚拟环境中
                2、进入到python的交互模式中
                3、在交互模式中输入
                    1、import django
                    2、django.VERSION
            2、在线安装 - 使用 pip
                1、终端中输入
                    pip install django(安装django的最高版本)
                    pip install django==1.11.8
                    注意:在虚拟环境中不要使用sudo
            2、离线安装
                1、下载所需要的django包
                2、在Linux中解压django
                    tar  - xvf Gjango-1.11.8.tar.gz
                 3、进入到Django文件夹中
                 4、安装
                     python setup.py install
        2、Windows中的安装
            1、在线安装
                控制台: pip3 install django==1.11.8
            2、离线安装
                1、下载django安装包
                2、解压django包
                3、进入到django包中
                    python setup.py install
    4、使用Django
        1、创建Django项目
            直接使用django-admin去创建Django项目
            1、找到项目文件夹(自定义)
            2、使用django-admin 指令
                django-admin startproject 项目名称
        2、启动Django项目
            1、进入到项目文件夹中
            2、通过manage.py 启动项目
                1、
                    python manage.py runserver
                    或 ./manage.py runserver
                    只能在本机访问
                    http://localhost:8000
                    http://127.0.0.1:8000
                2、
                    python manage.py runserver 0.0.0.0:8000
                    或 ./manage.py runserver 0.0.0.0:8000
                    允许在局域网内访问。可以通过IP地址访问,但是需要将setting.py文件中ALLOWED_HOSTS = []修改为ALLOWED_HOSTS = ["*"]
    5、Django结构介绍
        1、manage.py
            负责执行django中的各项操作的文件,又叫命令脚本文件
            如:
                1、启动服务
                2、创建应用
                3、创建管理员、用户
                ….
        2、主文件夹(名称与项目名称相同)
            存放项目的最基础的配置文件
            1、__init__.py
                项目初始化文件,每当服务器启动的时候,会自动执行,如果有自定义的初始化操作,需要放在该文件中
            2、urls.py
                项目的基础url(路由)配置文件
                路由:去哪里找执行的程序
            3、wsgi.py
                配置应用服务器的文件,暂时不用
            4、settings.py(重要)
                项目的主设置文件:应用:模板,数据库,语言,时区….
                1、BASE_DIR:项目的绝对路径
                2、DEBUG:调试模式
                    开发过程中,推荐使用Ture,上线运行时,必须改为False
                3、ALLOWED_HOSTS
                    设置允许访问本地项目的地址列表,如果不设置的话,只能本机访问,推荐用"*",表示任何机器都允许访问当前项目
                4、INSTALLED_APPS
                    指定已经安装的应用,如果有自定义应用的话,需要在此注册
                5、MIDDLEWARE:注册中间件
                6、ROOT_URLCONF:指定项目的基础路由配置文件
                7、TEMPLATES:指定模板的信息
                8、DATABASES:指定数据库的信息
                9、LANGUAGE_CODE:指定语言,允许修改为zh-Hans
                10、TIME_ZONE = 'UTC':指定时区,建议改为Asia/Shanghai
    6、settings的加载流程
        1、先加载globals_settings.py
            位于:/home/xdl/my_env/env3.5/lib/python3.6/site-packages/django/conf/globals_settings.py
        2、再加载项目中的settings.py
            注意:如果globals_settings中的内容与项目settings中的内容冲突的话,优先使用项目中的settings中的内容
    7、初始 django-admin 和 mangage.py
        1、在终端输入django-admin命令
            check
            compilemessages
            createcachetable
            dbshell
            diffsettings
            dumpdata
            flush
            inspectdb
            loaddata
            makemessages
            makemigrations
            migrate
            runserver
            sendtestemail
            shell:python3 manage.py shell ,进入django的交互环境,
            showmigrations
            sqlflush
            sqlmigrate
            sqlsequencereset
            squashmigrations
            startapp
            startproject#创建项目
            test
            testserver
        2、进入项目主目录文件夹,输入./manage.py
            [auth]
                changepassword #修改密码
                createsuperuser #创建超级用户
                示例:
                    1、首先需要创建一张用于存储用户信息:./manage.py migrate
                    2、创建用户:./manage.py createsuperuser
            [contenttypes]
                remove_stale_contenttypes

[django]
                check
                compilemessages
                createcachetable
                dbshell            #进入到Django数据shell交互模式
                diffsettings
                dumpdata
                flush
                inspectdb    #将数据表直接导出为Models
                loaddata
                makemessages
                makemigrations#创建数据库日志文件,记录Models的改动
                migrate            #将数据库日志文件同步到数据库中
                sendtestemail
                shell
                showmigrations
                sqlflush
                sqlmigrate
                sqlsequencereset
                squashmigrations
                startapp        #创建应用
                startproject
                test
                testserver

[sessions]
                clearsessions

[staticfiles]
                collectstatic
                findstatic
                runserver    #启动服务
    8、URL的使用
        1、urls.py
            默认在主文件夹中,包含所有的地址映射。
            每当一个请求产生后,都会到urls.py中进行地址的匹配,匹配上后再找对应的处理程序(View视图)去处理
        2、测试
            1、在主文件夹中,创建views.py
                作用:包含所有定义好的视图(处理程序)
                内容包括:
                    from django.http import HttpResponse
                    def fun_views(request):
                        '''视图,处理用户的请求并给出响应
                            request:表示用户的请求信息
                            HttpResponse:响应给客户端的内容'''
                        return HttpResponse("Hello django")
            2、在urls.py中追加
                from .views import *
                urlpatterns = [
                    url(r'^admin/',admin.site.urls),
                    //如果访问路径是fun/ 的话,则交给fun_views视图处理函数去处理
                    url(r'^fun/$',fun_views),//如果这里添加了自定义视图处理函数时,localhost:8000将会失效
                    //如果请求的URL在这里可以匹配多个,则只能执行第一个匹配到的
                ]
        3、url函数
            url函数的语法:
            url(regex,views,kwargs=None,name=None)
                1、regex:正则表达式,匹配请求的url
                2、views:url处理的视图函数,通常都是自定义的
                3、kwargs:字典,用来向views传参
                4、name:字符串,给url()起一个别名,主要在模板中匹配{%url%}一起使用
        4、url向view传参
            1、使用正则表达式传参
                使用正则表达式的子组传参,使用()
                urlpatterns=[
                    //访问路径必须是fun
                    url(r'^fun/$',fun_views),
                    //访问路径必须是fun
                    url(r'^fun/$',fun_views),
                    url(r'^fun/(\d+)',fun_arg1_views),
                ]
                注意
                    1、在url()中,一个子组()表示一个参数
                    2、在views.py中,对应的处理函数要根据url()中子组的个数,相应的定义参数,定义的参数要位于request之后
                练习:
                    1、访问地址:localhost:8000/18/0223/15,如何获取18 0223 15
                        def fun_arg3_views(request,num1,num2,num3):
                            return HttpResponse("%s %s %s"%(num1,num2,num3));
                        url(r'^(\d{2})/(\d{4})/(\d{2})$',fun_arg3_views),
            2、使用url()第三个参数,字典传参
                urlpatterns=[
                    url(r'^showname/$',show_views,{'name':"zhang",'age':25}),
                ]
                views.py:
                def show_views(request,name,age):
                    return HttpResponse(name+':'+str(age))
                注意:
                    1、视图处理函数中,必须声明参数
                    2、参数的名称 和 位置 必须要与字典中的名称和位置保持一致

3、Django中的应用
    1、什么是应用
        应用是网站中的一个独立的模块,包含独立的显示信息
        在项目主文件夹中一般不处理其他的请求,主要就做初始化设置 以及 地址的分发
        实际操作中,会将请求交给不同的应用去处理

2、创建应用
        1、命令: ./manage.py startapp 应用名称
        2、在settings.py中注册应用:
            INSTALLED_APPS = [
                'django.contrib.admin',
                'django.contrib.auth',
                'django.contrib.contenttypes',
                'django.contrib.sessions',
                'django.contrib.messages',
                'django.contrib.staticfiles',

'index',
            ]
    3、应用的结构组成
        1、migrations 目录
            存放数据库日志文件,是一个django与数据库交互的中间文件
        2、__init__.py
            应用的初始化操作文件
        3、admin.py
            应用的后台管理配置文件
        4、apps.py
            应用的属性设置文件,不需改动
        5、modles.py
            Modles模型文件
        6、tests.py
            测试模块,通常不用
        7、views.py
            定义视图的py文件
        练习:
            创建应用,并进行注册
            在day02_exer 中创建应用
            1、index - 主页面的应用
                ./manage.py startapp index
            2、news - 新闻的应用
                ./manage.py startapp news
            3、sports - 体育的应用
                ./manage.py startapp sports
            4、musics - 音乐的应用
                ./manage.py startapp musics
                在settings.py中的INSTALLED_APPS列表中添加以上应用
                INSTALLED_APPS = [
                    'django.contrib.admin',
                    'django.contrib.auth',
                    'django.contrib.contenttypes',
                    'django.contrib.sessions',
                    'django.contrib.messages',
                    'django.contrib.staticfiles',

'index',
                    'news',
                    'sports',
                    'musics',
                ]

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
url(r'^admin/', admin.site.urls),
]
urlpatterns += [
url(r'^music/', include('music.urls')),
url(r'^sport/',include('sport.urls')),
url(r'^news/',include('news.urls')),
#匹配空的时候一定要放在最后
url(r'^', include('index.urls')),
]

1、Django模板(Template)
    1、什么是模板
        就是一个网页,可以被view响应给用户
        目的是为了解决复杂的显示问题
    2、模板的设置
        1、BACKEND:指定模板的搜索引擎,不用改动(就是指定到哪里搜索模板)
        2、DIRS:指定模板所存放的目录,如果DIRS为空的话并且APP_DIRS为True,那么django会自动搜索每个应用中的templates文件作为模板管理目录
            DIRS = ['index.trmp','music.temp']
            推荐:
                1、DIRS保持为空
                2、在每个应用中,创建一个templates的文件夹
        3、APP_DIRS:值为boolean类型
            True:首先从DIRS中指定的文件夹中查找模板,如果没有找到指定模板的话,则再搜索templates目录
    3、模板的加载方式
        1、使用loader 获取模板,通过HttpResponse进行响应
            from django.template import loader
            def xxx(request):

     #1、通过loader加载模板
                t = loader.get_template('show.html')

     #2、将模板渲染成字符串
                html = t.render({})

     #3、通过HttpResponse响应回去
                return HttpResponse(html)
            说明:
                render({}),字典中的是数据,会传入html文档中,在HTML中通过{{字典的键}}取值,{{num1}}
                render({}),字典参数,可以通过locals(),获取该函数中的局部变量的字典,进行传递
        2、使用render直接加载
            return render(request,'模板名称',{})
    4、url()的name参数
        urlpatterns = [
            url(regex,views,kwargs=None,name=None)
        ]
        name:定义当前url的别名,允许在Template中使用该别名来找到对应的url(反向解析)

  反向解析:通过name 的值来匹配出对应的regex路径
    在Django模板中使用name实现连接
          {% url 'name值' %}
          如果url中有参数需要{% url 'name值' 参数1 参数2 …%}

  在视图中实现name别名反向解析出对应的URL地址

    需要引包:from django.shortcuts import reverse

    语法:

      1、无参数解析:reverse("别名")

      2、带参数解析:reverse("别名",args = (参数1,参数2….))

from django.shortcuts import render
from django.http import HttpResponse
from django.urls import reverse

Create your views here.

def index_views(request):
return HttpResponse("news index_views")

def reverse_views(rquest):
#反向解析url(不带参数),/news/reverse
#url = reverse("reverse")
#反向解析url(带参数),/news/reverse/2018/08
url = reverse('reverse_args',args=(2018,''))
return HttpResponse("反向解析出的URL:"+url)

5、模板的语法
        1、变量
           1、 作用:允许将后端的数据传递给模板(html),在模板中,会根据变量的实际值进行显示
           2、在Django中允许传递给模板作为变量的数据类型
                   数字,字符串,列表,元组,字典,函数,对象,类。 集合不可以

   3、变量语法
              变量们必须要封装到字典中才能传递给模板
                1、使用render加载模板 
                    dic = {
                        ’变量1’:‘值1’,
                        ‘变量2’:‘值2’,
                        ….
                    }
                    return render(request,'xx/html',dic)
                2、使用loader加载模板
                    dic = {
                        ’变量1’:‘值1’,
                        ‘变量2’:‘值2’,
                        ….
                    }
                    t = loader.get_template('x.html')

       #渲染成字符串是需要传递变量字典到模板中
                    html = t.render(dic)
                    return HttpResponse(html)
            4、在模板中使用变量:
                  {{变量名}}
                如果要取列表,字典,元组中的值要通过变量名.下标 或 变量名.键

def var_views(request):
#声明变量字典
l = ['金毛狮王','白眉鹰王','青']
t = ('潘林连','西门庆','武大郎')
dic = {
'SHZ':"水浒传",
'xyj':"西游记",
'hlm':'红楼梦'
}
def fun():
return '函数'
class Dog(object):
name = '阿拉斯基'
def eat(self):
return '吃狗粮'
vars = {
'num':15,
'str':'模板中的字符串变量',
'tup':t,
'list':l,
'dic':dic,
'fun':fun(),#等价于'fun':fun
'dog':Dog(),#等价于Dog

}  
return render(request,'02\_var.html',vars)


Title

num:{{ num }}

str:{{ str }}

tup:{{ tup }}

tup[0]:{{ tup.10 }}

list:{{ list }}

list[1]:{{ list.1 }}

dic:{{ dic }}

dic['xyj']:{{ dic.xyj }}

fun:{{ fun }}

dog:{{ dog }}

dog.name:{{ dog.name }}

dog.eat:{{ dog.eat }}

***********************************************************

tup:{{ t }}

tup[0]:{{ t.1 }}

list:{{ l }}

list[1]:{{ l.1 }}

dic:{{ dic }}

dic['xyj']:{{ dic.xyj }}

fun:{{ fun }}

dog:{{ Dog }}

dog.name:{{ Dog.name }}

dog.eat:{{ Dog.eat }}

2、标签
            1、什么是标签
                允许嵌套一些服务器端的逻辑运算到模板中
            2、语法
                {% %}
            3、常用标签
                1、{% if 条件 %} …{% endif %}
                    接受:not and or
                    但是 :and 和 or 不能同时出现
                    以下内容当成False处理:
                        空[]
                        空()
                        空{}
                        数字:0
                        空字符串
                        特殊对象:None
                2、{%if 条件 %}…{%else%}…{%endif%}
                3、
                    {%ifequal 值1 值2%}…{%endifequal%}:判断值1与值2是否相等
                    {%ifequal 值1 值2%}…{%else%}…{%endifequal%}
                4、{% for 变量 in 列表|元组|字典%}{%endfor%}
                    允许使用的内置变量(免声明)
                    forloop
                    1、forloop.counter:记录循环的次数
                    2、forloop.counter0:同上,但从0开始
                    3、forloop.revcounter:记录未被遍历的数量
                    4、forloop.revcounter0:同上,从0开始
                    5、forloop.first:布尔值,标记是否为第一个项目
                    6、forloop.last:布尔值,表示是否为最后一个项目

{% for str in l %}

数据{{forloop.counter0}}:{{ str }}


{% endfor %}

5、{%url%}
                6、{%static%}
                7、{%extends%}:用作模板继承

     8、comment 标签

      作用:在服务器端就被注释的内容,不会被渲染到客户端的

      >:客户端注释会被渲染到客户端,在其中的{{ 服务器代码}},回去执行解释
        3、过滤器
            1、作用
                在显示变量之前,允许对数据进行筛选或改变
            2、过滤器的语法
                {{var|过滤器}}
            3、常用过滤器
                1、{{var|upper}}:将var的数据变为大写
                2、{{var|lower}}:将var的数据变为小写
                3、{{var|add}}:
                4、{{var|floatformat:n}}:将var四舍五入到n为小数
                5、{{value|truncatechars:n}}:将value截取保留至n位字符(包含三个点…)

  自定义标签和过滤器

     步骤:
            1、在应用目录下创建templatetags目录
            2、在templatetags创建模块文件,并导入Django内部方法
          3、在模板最上方中加载自定义的模块文件,{% load 模块文件名%}

     自定义过滤器

        1、在templatetags目录下创建python模块,例如命名为tags.py

from django import template
register = template.Library()
@register.filter
def value_verification(value): # value为前端传递的参数

  '''最多传递两个参数'''
try:
int(value)
return True
except:
return False


{% load app01_func %}
{% if load|value_verification %}
  {{ num }} is a valid int number.
{% else %}
  {{ num }} is letter.
{% endif %}

     自定义标签

        1、simple_tag的代码方式与filter一样,不同的是在装饰器部分和前端调用的方式不同

from django import template
register = template.Library()
@register.simple_tag
def value_verification(value): # value为前端传递的参数
'''可以传递多个参数'''
try:
int(value)
return True
except:
return False

        2、前端模块中调用{% value_verification  num %}

     filter 和 simple_tag的区别

        1、filter可以用在if 条件判断中,但是最多只能有两个参数,可以将多个参数用特定字符拼接成一个字符串传递给后端,后端通过拆分获取多个参数

        2、simple_tag不能用在if、for语句中,可以传递多个参数

        3、模板中的调用方式不同

          1、filter将我们指定的函数变成了返回值可执行的方法{{ 参数1 | value_verification:参数2 }},冒号后面不能有空格

          2、simple_tag将函数功能变为标签功能{% value_verification  参数1 参数2…… as 返回结果的别名 %}
        4、静态文件的处理
            1、什么是静态文件

      在Django中,不被解释器动态解析的文件就称为静态文件,在Django中,物理路径(磁盘中真是存在的)是无法找到静态文件的
                模板中所用到的css,js,image等一些资源文件都是静态文件
            2、Gjango中静态文件的处理
                需要在settings.py中设置静态文件的访问路径 和 存储路径
                1、STATIC_URL:设置静态文件的访问路径
                    STATIC_URL = '/static/'
                2、STATICFILES_DIRS:设置静态文件的存储路径
                    1、STATICFILES_DIRS = (BASE_DIR,'static')

       2、STATICFILES_DIRS = (os.path.join(BASE_DIR,'静态文件目录名'))

       静态文件目录存放位置:

        1、所有应用中创建一个同名目录

        2、项目的根目录处也可以创建一个同名文件
                3、访问静态资源
                    1、
                    2、使用{%static%}访问静态资源

       {%static%}:表示的就是静态文件资源的访问路径(就是setting.py中STATIC_URL的值,STATIC_URL = '/static/')
                        1、模板的最顶层增加{%load static%}
                        2、使用静态资源文件时
                            <img src="{%static 'images/huiyuan.jpg'%}"

5、模板的继承
            1、什么是模板的继承
                当多个模板(网页)具备大部分相同的内容时,就可以使用继承的方式,将相同的内容继承过来,在增加/修改属于自己的内容即可
            2、模板继承的语法
                1、在父模板中增加{%block 名称%}…{%endblock%}
                    说明:名称不能重复
                2、在子模板中
                    1、在最顶层第一句话增加:
                        {%extends '父模板的名称'%}
                    2、增加block标记,编写属于自己的内容
                        {%block 名称%}//这里的名称要与父模板{%block 名称%}中的名称相同
                            属于子模板中自己的内容
                            //一旦引用次标记,则此处不再显示父模块中的内容
                        {%endblock%}

2、Django模型(Model)
    1、什么是模型
        模型,就是根据数据中数据表的结构而创建出来的class。
        数据库中的每一张表到编程语言中就是一个class
        数据库表中的每一个字段(列)可以被构建成class中的一个成员变量(属性),并且在模型中,完成对数据库的CRUD操作
            C:Create
            R:Retrieve(检索查找)
            U:Update
            D:Delete
    2、创建 和 使用模型 - ORM
        1、什么是ORM
            ORM:Object Relational Mapping(对象关系映射)
            简称:ORM, O/RM, O/R Mapping
            三大特征:
                1、数据表到类(class)的映射

       允许将表自动生成一个类,也允许将一个类自动生成一张表
                2、数据类型的映射
                    允许将表中字段的类型自动生成到编程语言中对应的数据类型,也允许将编程语言中的数据类型生成数据表中对应的字段类型
                3、关系映射
                    数据库中表的关联关系:
                        一对一,一对多(多对一),多对多
                    将表中的关联关系也映射到编程语言的class中,通过创建对象的关系来完成映射

       允许将类与类之间的关系自动映射成表与表之间的关系

      class A(object):

        name = None

      class B(object):

        a = A()#在表中通过外键进行关联

2、ORM的优点
            1、提高了开发效率,能够自动完成实体类到数据表的映射,

    2、可以省略庞大的数据访问层,即便不用SQL编码(语句),就能够完成对数据的CRUD操作
        3、创建 和 配置数据库
            1、创建数据库(支持中文)
                create database webdb default charset=utf8

      create database webdb default charset  utf8 collate utf8_general_ci
            2、Django中数据库的配置
                settings.py中配置数据库信息
                DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.mysql',
                        'NAME': 'webdb',
                        'USER': 'debian-sys-maint',
                        'PASSWORD':'Lo0r79JmxvMFNtA2',
                        'HOST':'localhost',
                        'PORT':'3306',
                    }
                }
                1、ENGINE:引擎
                    django.db.backends.mysql
                2、NAME:要连接到的数据库名称
                3、USER:用户名称
                4、PASSWORD:密码
                5、HOST:连接的主机,本机的话localhost/127.0.0.1/不写
                6、PORT:端口,3306
            4、安装pymysql

      注意:Django中要连接MySQL数据库的话要依赖于MySQLdb,通过pymysql解决问题
                pip install pymysql==0.7.11
            5、在主文件夹找找到__init__.py写入

import pymysql
                pymysql.install_as_MySQLdb()#转换为MySQLdb 
            6、启动django
                ./manage.py runserver
        4、数据库的同步操作
            1、./manage.py makemigrations
                作用:将每个应用下的models.py文件生成一个数据库的中间文件(映射成一个数据库日志文件),并存放在migrations目录中
            2、./manage.py migrate
                作用:将每个应用下的migrations目录中的中间文件(日志文件)同步到数据库中

    当migrations目录中没有中间文件时,会创建Django中自带的数据表

    

5、编写Models(重难点)
            1、注意:
                1、Models中的每个class都称之为 模型类(Model)或实体类(Entry)
                    实体:数据表中的一行记录,就是一个实体
                    实体完整性:确保每张表中的数据不能有重复的,数据表中的主键,是实现实体完整型的方式之一
                2、Models中的每个实体类,必须继承自models.Model
            2、示例:
                在models.py中
                from django.db import models
                class Publisher(models.Model):
                    name = models.CharField(max_length=30)
                    address = models.CharField(max_length=50)
                    city = models.CharField(max_length=20)
                    website = models.URLField()

from django.db import models
import datetime

Create your models here.

#实体类:Publisher
#对应到数据库中的一张,表表名为index_publisher(应用名_实体类名小写)
#该类中的每个属性,会对应到数据表中的每个字段啊
class Publisher(models.Model):
name = models.CharField(max_length=30,deafult='匿名')
address = models.CharField(max_length=60)
city = models.CharField(max_length=30)
country = models.CharField(max_length=30)
website = models.URLField()

class Author(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()
email = models.EmailField(null=True)

class Book(models.Model):
title = models.CharField(max_length=50)
publication_date = models.DateField(default=datetime.datetime.now())

6、Django中的字段类型以及字段选项
            1、字段类型(Field Types):映射到数据库表中的数据类型
                1、BooleanField():tinyint()
                2、CharField():varchar()
                3、DateField():date
                4、DateTimeField():datetime(6),6位精度 2018-08-27 16:43:20.000000 
                5、FloatField():double()
                6、FileField():varchar(100)
                7、EmailField():varchar(254)
                8、IntegerField():int(11)
                9、ImageField(upload_to=None):varchar(100)存放文件路径

      uimg=models.ImageField(upload_to='images/users/')

10、URLField():varchar(200)
                11、DecimalField(max_digits=7,decimal_places=2):decimal(7,2),通常用来表示钱

     12、TextField():longtext()存放大量数据
            2、字段选项:对生成的字段的说明信息
                1、null:是否允许为空,默认为False
                    name = models.CharField(max_length=30,null=True)
                2、default:为该字段设置默认值
                    name = models.CharField(max_length==30,default="匿名")

     3、db_cloumn

      指定当前属性(字段)对应到数据库表的列名,如果不指定则采用属性名作为列名

    3、说明:

      如果在原先实体类中添加属性(字段)时,必须给这个字段设置为允许为空(null=True)或者给一个默认值default=‘值’,否则会有如下提示     

     1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
       2) Quit, and let me add a default in models.py

7、数据的导入和导出(数据迁移)以及版本切换
            1、版本切换
                ./manage.py migrate 应用名称 版本号
                ./mansge.py migrete index 0001  //会将原先已经映射的数据表删除
            2、数据库的导出
                1、mysqldump -u… -p 数据库名 >文件.sql
                    导出所有的表结构以及数据
                2、mysqldump -u… -p -d 数据库名 >文件.sql
                    只导出所有的结构
            3、数据库的导入
                mysql -u.. -p 数据库名 < 文件.sql             4、通过数据库自动导出Models                 ./manage.py inspectdb >文件名.py
                表名index_book变为实体类名为IndexBook
                class IndexBook(models.Model):
                    title = models.CharField(max_length=50)
                    publication_date = models.DateField()

class Meta:
                        managed = False
                        db_table = 'index_book'

1、模型的数据库操作方法(CRUD)
    1、通过视图向DB中增加数据
        1、Entry.objects.create(属性=值,属性=值)

    返回值:创建好的实体,
            Author.objects.create(name='王宝强',age=33,email='wangbaoqiang@green.com')
        2、创建一个实体对象,并通过save()方法完成增加
            obj = Entry(属性=值,属性=值)
            obj.save()
        3、通过字典创建实体对象,在调用save()
            dic = {
                "name":"xx",
                "age": ,
                "email":"xx"
            }
            obj = Author(**dic)
            obj.save()
            示例:    
            dic = {"name":"陈羽凡","age":38,"email":"chenyufan@green.com"}
            obj = Author(**dic)
            obj.save()

def add_views(request):
#方法1、向Author实体中增加一条记录
ret = Author.objects.create(name='老舍',age=85,email='laoshe@163.com')
return HttpResponse(ret)#返回一个实体类对象,age是str,int都可以
#方法二
author = Author(name='巴金',age=75,email='bajin@163.com')
ret = author.save()
return HttpResponse(ret)#返回值为None
#方法三
dict = {
'name':'冰心',
'age':80,
'email':'bingxin@163.com',
}
author = Author(**dict)
ret = author.save()
return HttpResponse(ret)#返回None

2、查询操作(重难点)
    所有的查询都要在Entry.objects.基础上完成
    1、基本查询操作    
        语法:all()
        用法:Entry.objecsts.all()
        返回:QuerySet(查询结果集,是一个封装了若干对象的列表)
            , , ]>

    , , , ]>

def query_views(request):
#查询Author实体中所有的数据
#返回一个列表,其中封装了若干的对象
authors = Author.objects.all()
for au in authors:
print(au.name,au.age,au.email)
return HttpResponse('query ok')

2、查询接口
        1、all()
            Entry.objects.all()
            相当于:select * from …
        2、查询指定列的操作

     语法:values("列名1",‘列名2’…)
            Entry.objects.values('name')
            相当于:select name from …
            作用:查询所有记录的某一列的值
            返回值:QuerySet(查询结果集,是一个封装了若干字典的列表)

    注意:values()可以用在QuerySet(查询结果集)后面比如:all().values()

def query_views(request):
#查询Author实体中name 和 age的信息
authors = Author.objects.values('name','age')
print(authors)
# < QuerySet[ # {'age': 85, 'name': '老舍'}, # {'age': 85, 'name': '老舍'}, # {'age': 75, 'name': '巴金'}, # {'age': 80, 'name': '冰心'}] >
for au in authors:
print(au['name'],au['age'])
# 老舍 85
# 老舍 85
# 巴金 75
# 冰心 80
return HttpResponse('ok')

   3、values_list('列1',‘列2’)
            Entry.objects.values_list("name","age")
            相当于:select name,age from…
            返回值:QuerySet,是一个有若干元祖所组成的列表:

    注意:values_list()可以用在QuerySet(查询结果集)后面比如:all().values_list()

def query_views(request):
#查询Author实体中name 和 age的信息
authors = Author.objects.values_list('name','age')
print(authors)
#< QuerySet[ # ('老舍', 85), # ('老舍', 85), # ('巴金', 75), # ('冰心', 80)] >
for au in authors:
print(au[0],au[1])
# 老舍 85
# 老舍 85
# 巴金 75  
# 冰心 80
return HttpResponse('ok')

4、get()
            只查找一条记录是使用,也只能返回一条记录,如果查询返回多条记录的话,则报错
            Entry.objects.get(id=1)
            相当于:select * from …. where id=1
            返回值:Author object

     注意:查询多于一条记录或者没有查询到结果都会抛出异常

      1、get() returned more than one Author -- it returned 2!(Exception Type: MultipleObjectsReturned)

      2、Author matching query does not exist(Exception Type: DoesNotExist)
        5、exclude()
            作用:对给定条件取反
            Entry.objects.exclude(id=1)
            相当于:select * from …where not id=1
            返回值:, ]>
            Entry.objects.exclude(id=1,age=33)
            相当于:slect * from …where not(id=1 and age=3)
        6、order_by()
            Entry.objects.order_by('列名1',‘列名2’…)
            指定按照字段进行排序,如果是多个字段,中间用,逗号隔开。默认是按照升序排列,需要降序的话,只需在列名前加”-“符号即可
            返回值:QuerySet(查询结果集,是一个封装了若干对象的列表), , ]>

def query_views(request):
#查询Author实体中的数据按照年龄升序排列
authors = Author.objects.order_by('age')
print(authors)
#< QuerySet[ # < Author: 巴金 >,
# < Author: 冰心 >,
# < Author: 老舍 >,
# < Author: 老舍 >] >
for au in authors:
print(au.name,au.age)
#巴金 75
#冰心 80
#老舍 85
#老舍 85
return HttpResponse('ok')

7、filter()
            根据自定义条件查询结果集,可以是一个,也可以是多个,多个的话,条件用,逗号隔开。
            如果是多个条件的话,其内部是使用AND来进行条件连接的

    返回值:QuerySet(查询结果集,是一个封装了若干对象的列表)
            1、使用Entry的属性来作为filter()的条件
                示例:
                    1、Author.objects.filter(id=1)
                    相当于:select * from author where id=1
                    2、Author.object.filter(id=1,age=33)
                    相当于:select * from author where id=1 and age=3
            2、使用Field Lookups(查询谓词),完成复杂条件查询

     查询谓词:每一个独立的查询谓词就是一个独立的查询条件,所有支持使用查询条件的位置处,都允许适应查询谓词,get(),filter(),exclude()

      语法:属性__查询谓词=,双下划线
                1、__exact
                    作用:等值判断
                    Author.objects.filter(id__exact=1)
                    select * from author where id=1

      查看文档:https://docs.djangoproject.com/en/2.1/ref/models/querysets/

def query_views(request):
#查询Author实体中邮箱属性包含字符a
authors = Author.objects.filter(email__contains='a')
return render(request,'query.html',locals())

2、子查询
                    inner = Author.objects.filter(name__exact="王宝强").values("age")
                    authors = Author.objects.filter(age__gt=inner)等价于authors = Author.objects.filter(age__gt=inner[0]['age'])
3、修改操作
    1、修改单个对象
        1、通过get()获取要修改的实体对象
        2、通过实体对象修改属性值
        3、在通过实体对象的save()函数,实现保存
        auth = Author.objects.get(id=1)
        auth.name='宝强.王'
        auth.age = 45
        auth.save()
    2、批量修改(修改查询结果集的值)
        调用update()函数即可
        Author.objects.all().update(属性=值,….)
        说明:不能批量修改id
4、删除操作
    1、删除单个对象
        obj = Author.objects.get(id=1)
        obj.delete()
    2、批量删除
        Author.objects.all().delete()
5、F()操作 和 Q()操作
    1、F()操作
        作用:在执行中获取某列的值
        语法:F(‘列名’)
        from django.db.models import F
        Author.objects.all().update(age=F('age')+10)
    2、Q()操作

  作用:在查询条件中完成或(or)的操作

  语法:

    from django.db.models import Q

    Q(条件1)|Q(条件2)
        Author.objects.filter(id=1,age=35)//查询id为1并且age为35
        Author.objects.filter(Q(id_exact=1)|Q(age=35),name='王')//查询id为1或者age为35,并且那么为王的

  用法二:

    q = Q()    

    q.connector = 'or'   

    q.children.append(('id_exact',1))
    q.children.append(('age',35))
    Author.objects.filter(q)//查询id为1或者age为35

6、原生的数据库操作方法
    1、查询
        函数:raw()
        语法:Entry.objects.raw(sql语句)
    2、增删该
        def sql(requset):
            with connection.cursor() as cursor:
                sql = 'delete from index_author;'
                cursor.execute(sql)
                return render(……)
7、转发 与 重定向
    1、转发:
        转发就是将用户的请求发给另外一个视图进行处理,并将处理结果返回给用户请求的视图,最后响应给用户

  表现:地址栏不会发生改变

  原因:只有一次请求,所以地址栏就是最初请求的地址

def query_views(request):
authors = Author.objects.filter(isActive=True)
return render(request,'query.html',locals())
def delete_views(request,id):
author = Author.objects.get(id=id)
author.isActive=False
author.save()
return query_views(request)

  

2、重定向:(推荐使用)
        重定向就是告知并响应给用户哪个视图可以处理用户的请求,然后用户在根据响应的地址进行请求,最终得到结果

  表现:地址栏会显示最后一次请求的地址

  原因:重定向导致浏览器向服务器发送了两次请求

from django.http import HttpResponseRedirect
def query_views(request):
authors = Author.objects.filter(isActive=True)
return render(request,'query.html',locals())
def delete_views(request,id):
author = Author.objects.get(id=id)
author.isActive=False
author.save()
#重定向,参数是要重定向的地址
return HttpResponseRedirect('/02_query/')

from django.shortcuts import redirect
def query_views(request):
authors = Author.objects.filter(isActive=True)
return render(request,'query.html',locals())
def delete_views(request,id):
author = Author.objects.get(id=id)
author.isActive=False
author.save()
#重定向,参数是要重定向的地址
return redirect('/02_query/')

from django.shortcuts import reverse
def query_views(request):
authors = Author.objects.filter(isActive=True)
return render(request,'query.html',locals())
def delete_views(request,id):
author = Author.objects.get(id=id)
author.isActive=False
author.save()
#方向解析,参数是url的别名
url = reverse('query')
#重定向,参数是要重定向的地址
return redirect(url)

1、使用后台管理Models
    后台登录地址:http://localhost:8000/admin
    1、创建后台管理员
        ./manage.py createsuperuser
        Username:
        Email Address:可以为空
        Password:
        Password(agin)
    2、基本管理
        1、在应用中的admin.py中注册要管理的数据
            1、admin.py
                作用:注册需要管理的Models,只有在此注册的Model才允许被管理,否则无法管理
            2、注册Model
                from .models import *
                admin.site.register(Entry)
            3、修改models.py处理显示内容
                后台默认效果可读性不高
                def __str__(self):
                    return self.name//将后台显示Author object(一条记录),修改为该对象的name属性值
                在实体类中属性添加verbose_name="姓名"
                name = models.CharField(max_length=30,verbose_name="姓名")//显示name字段为姓名
                name = models.CharField(max_length=30,verbose_name="aa")//显示name字段为Aa
            4、通过内部类Meta实现展现的属性
                允许为每个model类设置内部类Meta来设置其展示形式
                class Author(models.Model):
                    ….
                    ….
                    class Meta:
                        1、db_table:指定该实体类对应到表的名称,该操作必须先同步到数据库
                        2、verbose_name:定义该实体类在admin中显示的名字(复数形式),会在该属性值的后面加s
                        3、verbose_name_plural:效果同上,是单数形式
                        4、ordering:在后台显示数据时的排序规则,取值是一个列表,默认是升序,降序在字段前面加‘-’

        ordering = ["uphone"]:按照电话号码升序

        ordering = ["-uphone"]:按照电话号码降序

5、ImageField数据类型
                在示例对象中添加该数据类型
                    1、pip install Pillow
                    2、picture = models.ImageField(
                        null=True,upload_to='static/upload/usrimg',verbose_name='头像')
                    null = True:因为数据表中原先有数据,现在添加新字段,需要允许为空
                    upload_to:表示上传后在项目中的保存路径
                    verbose_name:在后台显示的名字
    2、高级管理
        1、在admin.py中创建管理类,实现高级管理功能
            1、定义EntryAdmin类,继承自admin.ModelAdmin
            2、注册实体类
                class AuthorAdmin(admin.ModelAdmin):
                    pass
                admin.site.register(Author, AuthorAdmin)
            3、允许在EntryAdmin增加的属性
                1、list_display
                    作用:在显示实体信息的页面上,都显示哪些字段
                    取值:列表 或 元组
                2、list_display_links
                    作用:定义能够链接到具体实体页面的链接们
                    取值:由属性名组成的元组或列表
                    注意:取值必须要出现在list_display中,默认为list_display的第一个字段,
                3、list_editable
                    作用:定义在列表页面中允许被修改的字段
                    取值:由属性名组成的元组或列表
                    注意:list_editable中的值不能出现在list_display_links
                4、search_fields
                    作用:添加允许被搜索的字段
                    取值:由属性组成的元组或列表
                5、list_filter
                    作用:在列表的右侧增加过滤器,实现快速筛选
                    取值:由属性组成的元组或列表
                6、date_hierarchy
                    作用:在顶部增加一个时间选择器,所以取值必须是DateField 或 DateTieField的列
                7、fields
                    作用:在实体的详细页面中,显示哪些属性,并按照什么样的顺序显示
                    取值:由属性组成的元组或列表,空列表或元组无效
                8、fieldsets
                    作用:在实体的详细页面中,对属性进行分组
                    注意:fieldsets 与 fields不能共存
                    语法:
                        fieldsets = (

        #分组1
                            (‘当前分组的名称’,{'fields':(属性1,属性2…),‘classes’:(‘collapse’)}),

        #分组2
                            (‘当前分组的名称’,{'fields':(属性1,属性2…),‘classes’:(‘collapse’)}),
                            ……
                        )

      ‘classes’:(‘collapse’):表示可以被折叠

    9、filter_horizontal(“必须是具有多对多关系的属性”)和 filter_vertical(“必须是具有多对多关系的属性”)

      注意:

        当两个属性与raw_id_fields共存时,效果将会失效

      原图:

       filter_horizontal = ('publisher',):

      filter_vertical = ("publisher",)

    10、raw_id_fields("必须是具有一对多或多对多关系的属性")   

class BookAdmin(admin.ModelAdmin):
list_display = ('title','publication_date')
#book与publisher是多对一的关系,
#book域author是多对多的关系
raw_id_fields = ('publisher','author')
filter_horizontal = ('author',)#此处域raw_id_fields("author")共存将失效

    原图:

aaarticlea/png;base64,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" alt="" />

      raw_id_fields = ('publisher','author'):

aaarticlea/png;base64,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" alt="" />
2、Django连接查询(关系映射)
    1、一对一映射(1:1)
        1、什么是一对一
            A表中的一条记录只能与B表中的一条记录匹配关联

    B表中的一条记录也只能与A表中的一条记录相关联
            数据库中的实现:
                A表:设计主键
                B表:有主键,增加一列(作为外键),并应用A表中的主键值,还得增加一个唯一约束
        2、语法:

    在关联的两个类的任何一个类中,增加对另外一个类的应用

属性 = models.OneToOneField(Author,null=True)
            author = models.OneToOneField(Author,null=True)
            +-----------+-------------+------+-----+---------+----------------+
            | Field     | Type        | Null | Key | Default | Extra          |
            +-----------+-------------+------+-----+---------+----------------+
            | id        | int(11)     | NO   | PRI | NULL    | auto_increment |
            | name      | varchar(30) | NO   |     | NULL    |                |
            | age       | int(11)     | NO   |     | NULL    |                |
            | author_id | int(11)     | YES  | UNI | NULL    |                |
            +-----------+-------------+------+-----+---------+----------------+    

    | wife | CREATE TABLE `wife` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(30) NOT NULL,
    `age` int(11) NOT NULL,
    `author_id` int(11) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `author_id` (`author_id`),
    CONSTRAINT `wife_author_id_1672739f_fk_author_id` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8

#编写Wife实体了类,与Author做一对一关系映射
class Wife(models.Model):
name = models.CharField(max_length=30,verbose_name="姓名")
age = models.IntegerField(verbose_name='年龄')
#指定一对一的关联关系,引用自Author实体
author = models.OneToOneField(Author,verbose_name='丈夫')
class Meta:
db_table='wife'

3、查询

class Wife(models.Model):
                name = models.CharField(max_length=30,verbose_name='姓名')
                age = models.IntegerField(verbose_name="年龄")
                #增加一对一的关系映射
                author = models.OneToOneField(Author,null=True,verbose_name='丈夫')
            正向查询:通过wife 找 author

     #获取id为1的wife的信息
                w = Wife.objects.get(id=1)

     #在获取wife关联的author
                a = w.author

def oto_views(requset):
#先获取i的为1的wife的信息
wife = Wife.objects.get(id=1)
#再获取对应的author
author = wife.author
return render(requset,'03_oto.html',locals())

反向查询:通过author 找 wife
                a = Author.objects.get(id=1)
                w = a.wife
                wife 是由Django通过OneToOneField在Author中默认增加的一个属性,在数据库中没有体现
 2、一对多映射
        1、什么是一对多
            A表中的一条数据可以与B表中的任意多条数据匹配

    B表中的一条数据只能与A表中的一条数据相关联
        2、语法:

    在‘多’表中增加外键,对‘一’表表中的主键进行引用
            使用外键(Foreign Key)

    在‘多’实体中增加:
            属性 = models.ForeignKey(实体类)
            pub = models.ForeignKey(Publisher,null=True)
            +----+----------+------------------+--------+
            | id | title    | publication_date | pub_id |
            +----+----------+------------------+--------+
            |  1 | Python   | 1990-01-20       |      1 |
            |  2 | HTML/CSS | 1992-12-18       |   NULL |
            |  3 | Django   | 2018-08-18       |      3 |
            |  4 | HTML/CSS | 1992-02-18       |      2 |
            |  5 | JAVA     | 2018-08-19       |      3 |
            +----+----------+------------------+--------+  

   | book | CREATE TABLE `book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(30) NOT NULL,
  `publication_date` date NOT NULL,
  `publisher_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `book_publisher_id_ac4b162a_fk_publisher_id` (`publisher_id`),#普通索引
  CONSTRAINT `book_publisher_id_ac4b162a_fk_publisher_id` FOREIGN KEY (`publisher_id`) REFERENCES `publisher` (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 |

3、查询
            Book(M)和publisher(1)
                class Book(models.Model):
                    #增加一对多的关系
                    pub = models.ForeignKey(Publisher,null=True,verbose_name="出版社")
            1、正向查询 —— 通过Book 查询 Publisher
                book = Book.objects.get(id=1)
                publisher = book.pub

def otm_views(request):
#先查询id为1的book的信息
book = Book.objects.get(id=1)
#在查询book关联publisher
publisher=book.publisher
return render(request,'04_otm.html',locals())

2、反向查询 - 通过Publisher 查询 Book

     Django会通过ForeignKey()向关联的类中增加一个隐式属性:当前类_set,(当前类小写)
                p = Publisher.objects.get(id=1)
                bookset = p.book_set.all()//book_set是Django在Publisher实体类中添加book_set属性

 3、多对多映射
        1、什么是多对多
            A表中的一条记录可以与B表中的任意多条记录相关联
            B表中的一条记录可以与A表中的任意多条记录相关联
        2、在数据库中的体现
            必须创建第三张表,用于关联涉及到的两张表的数据
        3、语法:
            在涉及的到两个类中的任意一个类中,都可以对另外一个类的多对多的引用
                entry=models.ManyToManyField(Entry)
            示例:
                创建书籍与作者之间的多对多的引用
                    可以在书籍实体类中,增加对作者的引用
                    可以在作者实体类中,增加对书籍的引用
                class Book(models.Model):
                    ……..
                    author=models.ManyToManyField(Author)

    +-----------+---------+------+-----+---------+----------------+
    | Field     | Type    | Null | Key | Default | Extra          |
    +-----------+---------+------+-----+---------+----------------+
    | id        | int(11) | NO   | PRI | NULL    | auto_increment |
    | book_id   | int(11) | NO   | MUL | NULL    |                |
    | author_id | int(11) | NO   | MUL | NULL    |                |
    +-----------+---------+------+-----+---------+----------------+
    | book_author | CREATE TABLE `book_author` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `book_id` int(11) NOT NULL,
      `author_id` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `book_author_book_id_author_id_4fda6750_uniq` (`book_id`,`author_id`),#复合唯一索引book_id和author_id不能同时相同
      KEY `book_author_author_id_325bf96f_fk_author_id` (`author_id`),#普通索引
      CONSTRAINT `book_author_author_id_325bf96f_fk_author_id` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`),
      CONSTRAINT `book_author_book_id_19a45511_fk_book_id` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

4、查询
            class Book(models.Model):
                ……..
                author=models.ManyToManyField(Author)
            正向查询:通过Book找到对应的所有的Author
                #查询id为1的书籍的信息
                book = Book.objects.get(id=1)
                #查询book对应的所有的作者,通过关联属性查询对应的所有信息
                authors = book.author.all()

反向查询:通过Author查询所有的Book
                Django会通过ManyToManyField()在关联类中增加一个隐式属性
                属性名:当前类_set,(类名小写)
                #查询id为2的作者信息
                author = Author.objects.get(id=2)
                #再查询对应的所有的书籍
                bookList = author.book_set.all()

def mtm_views(request):
#正向查询
book =Book.objects.get(id=2)
authors = book.author.all()
#反向查询,book_set
author = Author.objects.get(id=3)
bookList = author.book_set.all()
return render(request,'05_mtm.html',locals())

HTTP通信协议
    1、什么是HTTP
        HTTP:Hyper Text Transfer Protocol(超文本传输协议)
        作用:规范了数据是如何打包以及传送的
    2、请求消息
        由请求起始行,请求消息头,请求主体


        请求主题:
            post和put两种提交方式会产生请求主体
    3、响应消息
        由响应起始行,响应消息头,响应主体

1、HttpRequest
    1、HttpRequest介绍
        HttpRequest,在Django中是对请求对象的封装体现,会封装请求过程中所有的信息,
        在Django中,HTTPRequest被封装成了Request被自动传到了视图处理函数中
        以双下划线或单下划线开头的不是HTTPRequest协议中的属性或方法,是Django自动添加的
        ['COOKIES', 'FILES', 'GET', 'META', 'POST', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_encoding', '_get_post', '_get_raw_host', '_get_scheme', '_initialize_handlers', '_load_post_and_files', '_mark_post_parse_error', '_messages', '_post_parse_error', '_read_started', '_set_post', '_stream', '_upload_handlers', 'body', 'build_absolute_uri', 'close', 'content_params', 'content_type', 'csrf_processing_done', 'encoding', 'environ', 'get_full_path', 'get_host', 'get_port', 'get_raw_uri', 'get_signed_cookie', 'is_ajax', 'is_secure', 'method', 'parse_file_upload', 'path', 'path_info', 'read', 'readline', 'readlines', 'resolver_match', 'scheme', 'session', 'upload_handlers', 'user', 'xreadlines']
    2、HTTPRequest中的主要内容
        1、request.scheme:请求协议
        2、request.body:请求主题(只有post和put请求方式时才会有请求主题)
        3、request.path:请求路径
        4、request.get_host():请求的主机地址或域名
        5、request.method:获取请求方法
        6、request.GET:封装了GET请求方式提交的数据
        7、request.POST:封装了POST请求方式提交的数据

    说明:

     GET,POST的返回值都是一个字典,字典的值是一个列表,但是通过request.GET['key']取出的一个字符串,(为什么?)

     答案:Django中通过重写__getitem__方法实现的

'''
QueryDict.__getitem__(key)
  返回给出的 key 的值。如果key 具有多个值,__getitem__()
返回最后(最新)的值。如果 key 不存在,
则引发django.utils.datastructures.MultiValueDictKeyError。(
它是Python 标准KeyError 的一个子类,所以你仍然可以坚持捕获KeyError。)
总结:Django中通过重写__getitem__方法实现的
'''

class MyDict():
def __init__(self,iterable):
self.data = iterable

def \_\_getitem\_\_(self, item):  
    return self.data\[item\]\[-1\]

dict = {
'name':['xdl','gj'],
'age':[25]
}
myDict = MyDict(dict)
print(type(myDict))#
print(myDict['name'])#gj

8、request.COOKIES:封装了cookie的数据
        9、request.META:封装了请求的元数据
            request.META["HTTP_REFERER"]:封装了请求的源地址

def requset_views(request):
#request,类型就是HTTPRequest
#request,封装的是所有与请求相关的内容
#print(dir(request))

#请求协议(方案),http  
scheme = request.scheme  
#请求主体  
body = request.body  
#请求资源的具体路径,根相对路径,/01\_requset/  
path = request.path  
#请求的主机地址或域名,127.0.0.1:8000  
host = request.get\_host()  
#请求方式,GET  
method = request.method  
#get方式请求的数据,得到的是一个字典,<QueryDict: {}>  
get = request.GET  
#post方式请求数据,<QueryDict: {}>  
post = request.POST  
#cookie中的数据,返回的是一个字典  
# {'csrftoken': 'w1TDCKqZakTz9IKn94luPeFjefTsGdDnRqGxzXdGJ5yNOQaWfeJC5MbUw0KRPWzo',  
# 'sessionid': '702s33knczrluqmeh15m9rvbasptd39i'}  
cookies = request.COOKIES  
#请求元数据,返回的是一个字典  
meta = request.META  
return render(request,'01\_request.html',locals())

3、获取请求提交的数据
        1、get请求方式
            request.GET["名称"]
            1、使用表单提交数据
                


            2、通过超链接拼接查询字符串
                
                此种方式,属于http标准,任何语言都可以使用
                Django中通过URL传递参数
                    url(r'01_test/(\d+)',test_views)
                此种方式,非http标准的,属于Django标准
        2、post请求方式
            request.POST["名称"]
            CSRF:Cross-Site Request Forgery(伪装):跨站点伪装攻击


                解决方案:
                    1、取消CSRF的验证
                        删除settings.py中MIDDLEWARE中的'CsrfViewMiddleware'中间件


                    2、开放验证权限,无需验证,直接进入
                        在视图处理函数之上增加一个装饰器@crsf_protect

       需要引包:from django.views.decorators.csrf import csrf_protect
                    3、必须要通过验证后才可以请求
                        在模板中

下第一行增加:{% scrf_token %}
                        在表单里面会出现一个隐藏域,value是一个可变的字符串
                        
    4、Django中的表单处理
        表单页面的get和post请求是由同一个视图(views)处理的,通过request.method判断

def login_views(request):
if request.method == 'GET':
return render(request,'03_login.html')
else:
return HttpResponse('用户名:%s,密码:%s'%(request.POST['uname'],request.POST['upwd']))

2、使用forms模块处理表单
    1、forms模块的作用
        通过forms模块,允许将表单与class相结合,允许通过class生成表单
    2、使用forms模块
        1、创建forms.py文件(在应用中创建)
        2、导入forms
            form django import forms
        3、创建class,必须继承自forms.Form一个class对应成一个表单
            class LoginForm(forms.Form):
                pass
        4、在class中创建属性(不用创建提交按钮)
            一个属性对应一个表单控件

# 表示评论内容的表单控件
class RemarkForm(forms.Form):
# 评论标题-文本框
subject = forms.CharField(label='标题')
# Email - type=‘Email’
email = forms.EmailField(label="邮箱")
#评论内容-文本域
message = forms.CharField(label="内容",widget=forms.Textarea)#widget=forms.PasswordInput表示密码框
#好评,中平,差评-select
topic_choices = (
(1,"好评"),
(2,"中评"),
(3,"差评"))
topic = forms.ChoiceField(label='评价',choices=topic_choices)
#是否保存
isSaved = forms.BooleanField(label='是否保存')

3、在模板中解析form对象
        1、注意
            1、需要自定义


            2、需要自定义按钮
        2、处理方法
            在视图中创建forms.Form的对象,并发送到模板中
            示例:
                form = RemarkForm()
                return render(request,'xx.html',locals())
            1、手动解析
                在模板中:
                    {% for field in form %}
                        {{field.lable}}:表示控件前面显示的文本
                        {{field}}:表示的就是控件
                    {% endfor %}
            2、自动解析
                1、{{form.as_p}}
                    将form对象中的每个属性使用p标记包裹起来,再显示在网页上
                2、{{form.as_ul}}
                    将form对象中的每个属性使用li标签包裹起来,再显示在网页上
                    注意:必须手动提供

                      3、{{form.as_table}}
                          将form对象中的每个属性使用tr标签包裹起来,再显示在网页上
                          注意:必须手动提供

          4、在视图中,通过forms.Form自动获取表单数据
              1、通过forms.Form的构造函数,接收post数据
                  form = XXXForm(requset.POST)
              2、需要让form通过验证后,再取值(必须要验证)
                  form.is_valid()
                      返回True:提交的数据已经通过验证,允许接收表单提交的数据
                      返回False:提交的数据验证未通过,无法取值
              3、获取表单中的数据
                  通过form.cleaned_data(字典)接收提交的数据

      def register_views(request):
      if request.method =="GET":
      form = RegisterForm()
      return render(request,'06_register.html',locals())
      else:
      form = RegisterForm(request.POST)
      if form.is_valid():
      cd = form.cleaned_data
      try:
      User.objects.get(uname=cd['uname'])
      return HttpResponse('用户名已存在')
      except ObjectDoesNotExist:
      User.objects.create(**cd)
      return HttpResponse("注册成功")

      1、forms模块
          1、forms的高级处理
              将Models和Forms结合到一起使用
              将Forms中的类和Models中的类关联到一起,实现属性的共享
              1、在forms.py中创建class,继承自forms.ModelForm
              2、创建内部类:Meta,关联Form和Model
                  属性:
                      1、model:指定要关联的Model类
                      2、fields:指定从Model中取哪些字段生成控件
                          1、取值:"__all__",全部的属性都要生成控件
                          2、取值:列表或元祖,声明允许生成控件的属性名称
                      3、labels:指定每个属性所关联的label,取值为字典
                          labels={
                              '属性名':"label文本",
                              '属性名':"label文本",
                              ………
                          }

      #创建class表示登录的表单,要关联Users实体类
      class UserLoginForm(forms.ModelForm):
      class Meta:
      #指定关联的model
      model = User
      #指定要生成的控件字段
      fields = ["uname","upwd"]
      #指定每个控件对应的label
      labels={
      "uname":"用户名",
      "upwd":"密码",
      }

      2、内置小部件
              1、什么是小部件
                  小部件(widget),表示的是生成到页面中的控件的类型以及其他的html属性
              2、常用的小部件
                  1、TextInput:type=“text”
                  2、NumberInput:type=“number”
                  3、PasswordInput:type=“password”
                  4、EmailInput:type=“email”
                  5、URLInput:type=”url“
                  6、HiddenInput:type=“hidden”
                  7、CheckboxInput:type=“checkbox”
                  8、Textarea:
                  9、Select:
              3、小部件的使用
                  1、继承自forms.Form
                      1、基本版
                          只指定控件的类型
                          属性=forms.CharField(
                              lable="标签",
                              widget=forms.小部件的类型
                              )
                          示例:
                              upwd=forms.CharField(label=“密码”,widget=forms.PasswordInput)
                      2、高级版
                          指定控件类型之外还允许设置html属性
                          属性=forms.CharField(
                                  label="标签",
                                  widget=forms.小部件类型(
                                      attrs = {
                                          "html属性名":"属性值",
                                          "html属性名":"属性值",
                                          ……
                                      }
                                  )

            )

      class WidgetForm(forms.Form):
      uname = forms.CharField(
      label="用户名称",
      widget=forms.TextInput(
      attrs={
      'name':'user_name',
      'placeholder':"请输入用户名称",
      'class':'form-control',
      }
      )
      )
      upwd = forms.CharField(
      label="用户密码",
      widget=forms.PasswordInput(
      attrs={
      'name':'user_pwd',
      'placeholder':'请输入密码',
      'class':'form-control',
      }
      )
      )

      2、继承自forms.ModelForm
                      class Widget2Form(forms.ModelForm):
                          class Meta:
                              model = User
                              fields= "__all__"
                              labels={
                                  "属性1":"标签1",
                                  "属性2":"标签2",
                                  ….
                              }
                              widgets={
                                  "属性1":forms.小部件类型(attrs={}),
                                  "属性2":forms.小部件类型(attrs={}),
                                  ……..
                              }

      class Widget2Form(forms.ModelForm):
      class Meta:
      model=User
      fields=("uname","upwd")
      labels={
      "uname":'用户名称',
      "upwd":"用户密码",
      }
      widgets={
      'uname':forms.TextInput(
      attrs={
      "placeholder":'请输入用户名'
      }
      ),
      'upwd':forms.PasswordInput(
      attrs={
      'placeholder':"请输入密码"
      }
      )
      }

      2、cookies
          1、什么是cookies
              cookies是一种数据的存储技术,只能保存字符串
              允许将一段文本保存在客户端上(浏览器)的一种技术,并可以长时间保存
          2、cookies的使用场合
              1、记住密码
              2、保存搜索关键词
          3、在Django中使用cookies
              1、设置cookies的值(将数据保存客户端)
                  语法:
                      响应对象.set_cookie(key,value,[expires])
                          key:cookie的名字
                          value:cookie的值
                          expires:保存时间,以s为单位,如果不给该参数,则浏览器关闭,cookie失效
                      示例:
                          响应对象.set_cookie('uname','xdl',60*60*24*366)
                      响应对象:HttpResponse,render,HttpResponseRedirect,redirect
                  1、不使用模板(HttpResponse)
                      resp = HttpResponse("给客户端的一句话")
                      resp.set_cookie('key','value',expires)
                      return resp
                  2、使用模板(render)
                      resp = render(reuqest,'xxx.html',locals())
                      resp.set_cookie('key','value',expires)
                      return resp
                  3、重定向(HttpResponseRedirect/redirect)
                      resp = HttpResponseRedirect('/地址/')
                      resp.set_cookie('key','value',expires)
                      return resp
              2、获取cookies的值(将数据从客户端中获取出来)
                  通过request.COOKITES(返回的是一个字典,通过键值可以取值)
                  获取当前访问站点下所有的cookies的信息

        3、删除cookie

          响应对象.delete_cookie('key')
      3、session-会话
          1、什么是session
              session(会话),实际上就是在服务器上为每个浏览器开辟的一段空间,用于保存相关的请求信息


          2、session的使用场合
              session也是为了存储数据而存在的
              通常会把服务器经常要用到的数据保存进去
          3、Django中使用session
              1、设置session的值
                  request.session['key']=value
                  request.session.set_expiry(time):
                  设置session的过期时间,如果设置为0的话,则表示关闭浏览器session就失效
              2、获取session的值
                  value = request.session['key']                
                  value = request.session.get('key')
              3、删除session的值
                  del request.session['key']
              4、在setting.py中,有关session的设置
                  1、SESSION_COOKIE_AGE
                      作用:设置sessionID在cookies中的保存时长,默认为15天
                      示例:
                          SESSION_COOKIE_AGE=60*6024
                  2、SESSION_EXPIRE_AT_BROWSER_CLOSE(建议使用)
                      作用:设置关闭浏览器时清除服务器上对象的session空间
                      示例:
                          SESSION_EXPIRE_AT_BROWSER_CLOSE = True

      cookie 存取中文

      def setCookie_views(request):
      uname = '张三丰'
      #将uname转化为unicode
      uname = json.dumps(uname)
      resp = HttpResponse('set cookie ok')
      resp.set_cookie('name',uname)
      return resp
      def getCookie_views(requset):
      uname = requset.COOKIES['name']
      #将unicode码转换为中文
      uname = json.loads(uname)
      return HttpResponse(uname)


      Title

      上传图片

        前段页面: 

          上传图片  

      {% csrf\_token %}

          访问图片:通过views函数返回这个对象集合,然后在前端循环获取图片路径.url

      {% for show in p %}
      {% if show.pic %}

      {% endif %}
      {% endfor %}

        后端配置:

          配置settings文件

      MEDIA_ROOT = os.path.join(BASE_DIR,'media').replace('\\','/')
      MEDIA_URL = '/media/'

          配置urls文件,主路由文件

      from django.conf.urls import url, include
      from django.contrib import admin
      from sale import views
      from django.conf import settings
      from django.conf.urls.static import static
      urlpatterns = [
      url(r'^admin/', admin.site.urls),
      url(r'^$',views.index,name='index'),
      url(r'^userinfo/',include('userinfo.urls')),
      ]+ static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

          views.py视图

      def salecar(request):
      new_a = Aid()#实体类
      pic = request.FILES.get('pic')
      new_a.pic = pic
      new_a.save()
      return render(request,'infomessage.html')