django学习第一天

jinja2模板渲染简单使用

  • 下载安装
    pip install jinja2

使用示例

  • html文件中写法
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="x-ua-compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Title</title>
    </head>
    <body>
        <h1>姓名:{{name}}</h1>
        <h1>爱好:</h1>
        <ul>
            {% for hobby in hobby_list %}
            <li>{{hobby}}</li>
            {% endfor %}
        </ul>
    </body>
    </html>
    
    
  • 视图中写法
    from wsgiref.simple_server import make_server
    from jinja2 import Template
    
    def index():
        with open("index2.html", "r",encoding='utf-8') as f:
            data = f.read()
        template = Template(data)  # 生成模板文件
        ret = template.render({"name": "于谦", "hobby_list": ["烫头", "泡吧"]})  # 把数据填充到模板里面
        return [bytes(ret, encoding="utf8"), ]
    

MVC和MTV框架

  • MVC
    web服务器开发领域里著名的MVC模式,所谓MVC就是把web应用分为模型(M),控制器(C)和视图(V)三层,结构说明如下:
    M:models 数据库相关操作 V:views 视图,也就是业务逻辑相关操作 C:controller 控制器,也就是通过路径找到对应视图函数

  • MTV
    Django的MTV模式本质上和MVC的一样的,也是为了各组件间保持松藕合关系,只是定义上有些许不同。
    M:models 数据库相关操作 T:templates html文件相关操作(模板渲染等) V:views 视图,也就是业务逻辑相关操作 再加上一个url控制器,也就是通过路径找到对应视图函数

WSGI

  • WSGI(Web Server Gateway Interface)就是一种规范,它定义了web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。
    开发的项目分为两个部分的程序 1、服务器程序 socket相关功能的模块,wsgiref、uwsgi等等,负责接收网络请求并解析网络请求相关数据,分装加工成一些可用的数据格式,格式大家都是统一的,方便应用程序的开发 2、应用程序 就是使用接收到的网络请求相关数据,进行逻辑代码的开发,比如数据库相关操作,数据结构的调整,文件操作等等。。

django

  • Django是MTV模式架构的框架。历史版本介绍,参考官网。
  • 下载安装
    pip install django==1.11.9
  • 创建项目
    可以通过指令来创建,将来还可以通过IDE来进行创建,先看指令的写法
    django-admin startproject mysite #mysite是自己的项目名称
    执行上面的指令之后会生成如下的目录,当前目录下会生成mysite的工程,里面有个主目录和我们创建的项目目录同名,在项目目录下有个manage.py文件,在主目录下有setting.pyurls.pywsgi.py,每个文件的功能介绍如下:
    manage.py ----django项目里面的工具,通过它可以调用django shell和数据库,启动关闭项目与项目交互等,不管你将框架分了几个文件,必然有一个启动文件,其实他们本身就是一个文件 settings.py ----包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量 urls.py ---- 负责把URL模式映射到应用程序 wsgi.py ---- runserver命令就使用wsgiref模块做简单的web server,后面会看到runserver命令,所有与socket相关的内容都在这个文件里面了,目前不需要关注它
    在一个项目中可以有多个应用,每个应用完成项目的部分功能,比如微信项目,其中有很多应用,比如朋友圈功能、聊天、支付等等。在django框架看来,每个应用都有自己的逻辑部分,数据库部分等等,所以我们进行业务逻辑开发的时候,需要创建应用在写逻辑。

运行项目

  • 命令运行
    python manage.py runserver 127.0.0.1:8000 ip和port可以不用写,不写的话,默认是 127.0.0.1:8000 运行之后,通过浏览器访问127.0.0.1:8000,当看到页面为It worked!表示成功

创建应用

  • 创建应用的指令如下:需要借助到我们创建的项目中的manage.py文件
    python manage.py startapp app01 #app01为创建的应用名称
  • 创建完应用后的目录介绍
    models.py 数据库相关内容 views.py 视图,业务逻辑代码相关内容 tests.py 用来写一些测试代码,用来测试我们自己写的视图 ...其他的后面再说

pycharm创建django框架结构项目

  • 需要用到专业版,此处省略,自己百度创建

通过django来完成一个简单的web项目

  • 第一步 创建视图函数
    在应用文件夹下面的views.py文件中写视图函数,比如: def home(request): #request--environ 请求相关数据,request叫作HTTPRequest对象 return render(request,'home.html') #render方法用来打开html文件,对文件进行模板渲染,第一个参数是request,第二个参数是html文件路径(这里只写了文件名称,因为django会自动去templates文件下面去找html文件),渲染完成后,返回响应页面数据,最终交给wsgi中的socket将页面数据返回给客户端。

  • 第二步:创建html文件
    如果视图响应的是一个html文件,那么就需要再项目目录下templates文件夹下创建一个html文件。
    为什么django能够自动找到templates文件夹下面的html文件呢?也就是我们使用render方法时,只写了一个html文件名称,就能够自动找到这个html文件,是因为在django的默认配置中有一个关于templates模板相关功能的配置项,里面指定了html文件的存放目录,找到主目录下面的settings.py,打开这个文件,找到TEMPLATES这个配置,内容如下:

    ```
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 项目根路径
    
    TEMPLATES = [
        {
      'BACKEND': 'django.template.backends.django.DjangoTemplates',
      'DIRS': [os.path.join(BASE_DIR, 'templates')] #DIRS指的就是html文                              件存放路径的配置,注意,有些版本的django或者通过指令来创建项目时,这个DIRS的配置是空的,需要我们自己指定html文件的存放路径,所以如果你发现这个DIRS为空,我们需要自定来配置路径,可以按照现在这种方式来写
      ,
      'APP_DIRS': True,
      'OPTIONS': {
          'context_processors': [
              'django.template.context_processors.debug',
              'django.template.context_processors.request',
              'django.contrib.auth.context_processors.auth',
              'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    ```
    
  • 第三步 创建url路径和函数的映射关系
    在项目主目录的urls.py文件中的urlpatterns中写上如下内容
    from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/',admin.site.urls),#这个是django内置的 url(r'^home/',views.home) ]
    url中正则路径如何找到对应的函数,简单分析
    #伪代码 import re path = request.path 当前请求路径 for item in urlpatterns: ret = re.match(item.regex,path) #item.regex -- ^home/ if ret: item.func(request) #item.func--views.home 函数 break else: pass

简单介绍几个request对象的属性

  • 在views.py文件的视图函数中打印以下几个属性
    def home(request): print(request) #wsgi封装的一个对象,WSGIRequest类的对象 print(request.path) #/home/ 请求路径 print(request.method) #GET 请求方法 print(request.POST) #获取post请求提交过来的数据 #<QueryDict:{'username':['root'],'password':['123']}> uname = request.POST.get('username')#取出username数据 return render(request,'home.html')

完成一个简单登录功能

  • views.py内容如下
    一个视图函数搞定登录功能 def login(request): if request.method == 'GET': return render(request,'login.html') else: print(request.POST) #<QueryDict:{'username':['root'],'password':['123']}> uname = request.POST.get('username') pwd = request.POST.get('password') if uname == 'root' and pwd == '123': return render(request,'xx/home.html') else: return HttpResponse("用户名或密码错误!重新登录")

  • urls.py内容如下

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    urlpatterns = [
          url(r'^home/',views.home),
          url(r'^login',views.login),
          
      ]
    ```
    
  • login.html内容如下
    <form action='/login/' method='post'> 用户名:<input type='text' name='username'> 密码:<input type='password' name='password'> <button>提交</button> </form>

url路由系统

  在django中,url中的路径写法是正则,正则里面有无名分组正则,有有名正则分组,那么对应django中的功能,我们称之为无名分组路由和有名分组路由

无名分组路由

  看写法,urls.py文件中内容如下
  ```
  urlpatterns = [
        url(r'^books/(d+)/(/d+)/',views.book),
        #正则里面()分组正则,会将分组中的正则匹配到的内容作为返回值返回
  ]
  简单分子,伪代码
  当用户请求的路径是它:  /books/2019/8
  url(r'^books/(d+)/(d+)',views.book),
  上面路由做的事情:
  re.match(^books/(d+)/,/books/2019/)
  2019和8作为位置参数交给了要执行的book视图函数
  视图函数book的写法
  def book(request,xx,oo):
        xx = 2019
        oo = 9
        pass
  ```
  • 视图views.py文件中函数的写法
    #位置传参,url中正则^books/(d+)/(d+)/,那么第一个()分组匹配到的数据,作为book函数的第二个参数,第二个()分组匹配到的数据,作为book的第二个参数 def book(request,year,month): print('year',year,'month',month) #return HttpResponse('%s所有书籍'%year) return HttpResponse('%s年%s月所有书籍'%(year,month))

使用url路由系统时需要注意的几个点

  ```
  1.urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
  2.若要从URL中捕获一个值,只需要在它周围放置一对圆括号(正则分组匹配)
  3.不需要添加一个前导的反斜杠(也就是写在正则最前面的那个/),因为每个url,都有。例如,应该是^home/ 而不是^/home/。
  4.每个正则表达式前面的r,是可选的但是建议加上
  5.^home$  以什么结尾,以什么开头,严格限制路径
  ```

有名分组路由

  其实就是正则中的有名分组,看实例
  • urls.py文件中的写法
    urlpatterns = [ url(r'^admin/',admin.site.urls), url(r'^books/(?P<year>d+)/(?P<month>d+)/',views.book), #{'year':2020,'month':6},url将有名分组正则匹配出来的数据,交给了book视图函数作为关键字参数来使用 ]
  • views.py文件中函数的写法如下
    #^books/(?P<year>d+)/(?P<month>d+)/ #获取到url中的有名分组正则匹配到的数据,那么函数形参名称必须和有名分组正则的那个名称相同才可以,也就是按照上面的url来看的话,函数的形参必须是year和month这个两个名称,并且关键字传参不需要考虑函数形参的位置。 def book(request,month,year): #print('year',year,'month',month) print(request.path) #/book/2020/6/ #return HttpResponse('%s所有书籍'%year) return HttpResponse("%s年%s月所有书籍"%(year,month))

补充说明

  ```
  当用户通过浏览器访问django框架完整的项目中的某个路径时,如果用户在输入网址路径的最后,没有加上斜杠/,比如http://127.0.0.1:8000/test,那么django会先将用户输入的网址路径加上一个后置/,也就是将路径变成http://127.0.0.1:8000/test/,然后给浏览器发一个重定向的响应操作,状态码为301,那么浏览器拿到这个重定向操作之后,就会自动发起一个这样的路径请求http://127.0.0.1:8000/test/,所以当我们打开浏览器控制台的network功能查看请求过程时,会看到两个请求,一个有斜杠,一个没有。第二个有斜杠的才会走到我们的url.py文件中的路径配合和分发对应的视图的地方。

我们可以通过一个配置项,告诉django,不要自动加路径后面的斜杠了,但是需要注意的就是你自己写的url中的正则,也别加后面的斜杠,不然正则匹配不到。
配置项直接写在settings配置文件中,任意位置
APPEND_SLASH = False #False表示告诉django,不加路径后面的斜杠,默认值是True
```

视图函数中指定默认值

  • views.py文件
    在路由没有匹配任何参数的时候,num使用自己的默认值 在路由中有分组匹配数据的动作,比如url(r'^test/(d+)/',views.test),用户输入网址http://127.0.0.1:8000/test/22/,那么22就匹配到了,会作为参数传给我们的test函数,那么num的值就变成了22 def test(request,num=10): print('number>>>',num) return HttpResponse('test')
  • urls.py文件
    urlpatterns = [ url(r'^test/(d+)/',views.test), ]
原文地址:https://www.cnblogs.com/weiweivip666/p/13283133.html