框架--1django

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了框架--1django相关的知识,希望对你有一定的参考价值。

web框架

  框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,以避免重复造轮子。

  所有的Web应用,本质上是一个socket服务端,用户的浏览器其实就是一个socket客户端。

 

import socket

def handle_request(client):

    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK\\r\\n\\r\\n".encode("utf8"))
    client.send("<h1 style=\'color:red\'>Hello, yuan</h1>".encode("utf8"))

def main():

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((\'localhost\',8001))
    sock.listen(5)

    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == \'__main__\':

    main()
View Code

 

接受HTTP请求、解析HTTP请求、发送HTTP响应这些底层功能由专门的服务器软件实现,通过接口WSGI:Web Server Gateway Interface完成。

 

MTV模式

       Model(模型):负责业务对象与数据库的对象(ORM)

       Template(模版):负责如何把页面展示给用户

       View(视图):负责业务逻辑,并在适当的时候调用Model和Template

       此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

 

环境:

   通过“cmd”打开一个新的命令提示符窗口,直接输入:“django-admin.py”,如果提示:“\'django- admin.py\' 不是内部或外部命令,也不是可运行的程序或批处理文件,那先下载安装,之后配好环境变量。

创建一个django项目

  在django已经安装完毕、环境变量也配置好了,执行创建django项目的命令。

  通过命令:“django-admin.py startproject [projectname]”在当前目录下建立一个名为[projectname]的项目。

  pycharm创建如下:

  注:需要确保py的打开方式是python解释器,不是则右键任意py文件选择默认的打开方式为python解释器就好啦!

创建好的django项目长这样:

     

注:若是命令创建,则没有templates目录

manage.py

是与项目进行交互的命令行工具集的入口,是Django中的项目管理器,运行命令:

python manage.py 可以查看manage.py 的相关命令

 

与项目同名的子目录

这个目录是项目的一个容器,包含项目的一些基本配置,文件名理论上可以随意修改,但并不建议这样做。这是因为配置文件中很多配置引用到这个文件名,无需修改。

其中的文件

1.wsgi.py

wsgi(Python Web Server Gateway Interface)即Python服务器网关接口,是python应用与Web服务器之间的接口。

2.urls.py

URL配置文件。Django项目中所有地址(页面)都需要我们去配置URL。

3.settins.py

BASE_DIR:项目的根目录;
SECRET_KEY:安全码;
DEBUG:调试,实际生产中需要将其值设置为* false *;
ALLOWED_HOSTS:设置允许的外界访问的地址;
INSTALLED_APPS:记录加载的应用;
MIDLEWEAR:自带的工具集;
ROOT_URLCONF:URL根文件的配置文件;
TEMPLATES:模板文件,模板指的是一个个
html文件;
WSGI_APPLICATION:
DATABASES:数据库文件,默认是sqlite3,如果要使用其他数据库可以到Django官网有关数据库配置的文档了解;
AUTH_PASSWORD_VALIDATORS:与密码认证有关;
LANGUAGE_CODE:语言,默认是un-es即美式英语;
TIME_ZONE:时区;
STATIC_URL:静态文件(CSS,javascript,images等)的地址。

4.init.py

声明模块,内容默认为空。

 

STATIC文件还可以配置STATICFILES_DIRS,指定额外的静态文件存储位置。
    #  STATIC_URL的含义与MEDIA_URL类似。

    # ----------------------------------------------------------------------------
    #注意1:
        #为了后端的更改不会影响前端的引入,避免造成前端大量修改

        STATIC_URL = \'/static/\'               #引用名
        STATICFILES_DIRS = (
            os.path.join(BASE_DIR,"statics")  #实际名 ,即实际文件夹的名字
        )

        #django对引用名和实际名进行映射,引用时,只能按照引用名来,不能按实际名去找
        #<script src="/statics/jquery-3.1.1.js"></script>
        #------error-----不能直接用,必须用STATIC_URL = \'/static/\':
        #<script src="/static/jquery-3.1.1.js"></script>

    #注意2(statics文件夹写在不同的app下,静态文件的调用):

        STATIC_URL = \'/static/\'

        STATICFILES_DIRS=(
            (\'hello\',os.path.join(BASE_DIR,"app01","statics")) ,
        )

        #<script src="/static/hello/jquery-1.8.2.min.js"></script>

    #注意3:
        STATIC_URL = \'/static/\'
        {% load staticfiles %}
       # <script src={% static "jquery-1.8.2.min.js" %}></script>
settings的配置

 

 

在项目里创建应用

  python manage.py startapp myblog

并添加应用名到settings.py中的INSTALLED_APPS中(注:应用名不可以与模块名相同)

应用的文件结构:

  • migrations:一个数据迁移的模块,内容自动生成
  • admin.py 该应用的后台管理系统
  • apps.py 该应用的一些配置,Django-1.9以后自动生成
  • models.py 数据模块,使用ORM框架
  • tests.py 自动化测试的模块
  • views.py 执行响应的代码所在模块,是代码逻辑处理的主要地点,项目中大部分代码在这里编写

启动django项目

python manage.py runserver 8888

 注:此处指指定端口,若不指定IP和端口,默认为http://127.0.0.1:8000/

 

访问时的默认页面为

 

django重要文件介绍:

urls.py 路由配置系统(URLconf)

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。

    urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]


参数说明:
一个正则表达式字符串
一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
可选的要传递给视图函数的默认参数(字典形式)
一个可选的name参数

URLconf的正则字符串参数

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r\'^articles/2003/$\', views.special_case_2003),
    url(r\'^articles/([0-9]{4})/$\', views.year_archive),
    url(r\'^articles/([0-9]{4})/([0-9]{2})/$\', views.month_archive),
    url(r\'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$\', views.article_detail),
]
    NOTE:
    1 一旦匹配成功则不再继续
    2 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
    3 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
    4 每个正则表达式前面的\'r\' 是可选的但是建议加上。

一些请求的例子:

    /articles/2005/3/ 不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
    /articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。
    /articles/2005/03/ 请求将匹配列表中的第三个模式。Django 将调用函数
                       views.month_archive(request, \'2005\', \'03\')。
注意

有名分组(named group)

上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。

在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中name 是组的名称,pattern 是要匹配的模式。

下面是以上URLconf 使用命名组的重写:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r\'^articles/2003/$\', views.special_case_2003),
    url(r\'^articles/(?P<year>[0-9]{4})/$\', views.year_archive),
    url(r\'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$\', views.month_archive),
    url(r\'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$\', views.article_detail),
]
View Code

这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数

在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误 —— 你可以在你的视图函数定义中重新安排参数的顺序。当然,这些好处是以简洁为代价;有些开发人员认为命名组语法丑陋而繁琐。

URLconf 在什么上查找

URLconf 在请求的URL 上查找,将它当做一个普通的Python 字符串。不包括GET和POST参数以及域名。

例如,http://www.example.com/myapp/ 请求中,URLconf 将查找myapp/

在http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找myapp/

URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POSTGETHEAD等等 —— 都将路由到相同的函数。

捕获的参数永远是字符串

每个捕获的参数都作为一个普通的Python 字符串传递给视图,无论正则表达式使用的是什么匹配方式。例如,下面这行URLconf 中:

url(r\'^articles/(?P<year>[0-9]{4})/$\', views.year_archive),

views.year_archive() 的year 参数将是一个字符串

 

指定视图参数的默认值

有一个方便的小技巧是指定视图参数的默认值。 下面是一个URLconf 和视图的示例:

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r\'^blog/$\', views.page),
    url(r\'^blog/page(?P<num>[0-9]+)/$\', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):

    ...
View Code

在上面的例子中,两个URL模式指向同一个视图views.page —— 但是第一个模式不会从URL 中捕获任何值。如果第一个模式匹配,page() 函数将使用num参数的默认值"1"。如果第二个模式匹配,page() 将使用正则表达式捕获的num 值。

 

#At any point, your urlpatterns can “include” other URLconf modules. This
#essentially “roots” a set of URLs below other ones.

#For example, here’s an excerpt of the URLconf for the Django website itself.
#It includes a number of other URLconfs:


from django.conf.urls import include, url

urlpatterns = [
   url(r\'^admin/\', admin.site.urls),
   url(r\'^blog/\', include(\'blog.urls\')),
]

传递额外的选项给视图函数(了解)

URLconfs 具有一个钩子,让你传递一个Python 字典作为额外的参数传递给视图函数。

django.conf.urls.url() 函数可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。

 

 

views.py 视图

一个视图函数,或者简短来说叫做视图,是一个简单的Python函数,它接受web请求,并且返回web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了能够把代码放在某个地方,惯例是把视图放在叫做views.py的文件中,然后把它放到你的项目或者应用目录里。

 

一个返回当前日期和时间作为HTML文档的视图样例:

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

逐行分解

  • 首先,我们从 django.http模块导入了HttpResponse类,以及Python的datetime库。
  • 接着,我们定义了current_datetime函数。它是一个视图函数。每个视图函数都应接收HttpRequest对象作为第一个参数,一般叫做request。
  • 注意视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够精确地反映出它的功能。
  • 这个视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都要返回HttpResponse对象

http请求-响应过程中有两个核心对象:

http请求对象:HttpRequest

http响应响应:HttpResponse

所在位置:django.http

其中封装好的函数

render函数

---------------render(request, template_name[, context])

结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。

参数:
     request: 用于生成响应的请求对象。

     template_name:要使用的模板的完整名称,可选的参数

     context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。

     content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。

     status:响应的状态码。默认为200。

redirect函数

----------redirect(/uri)

总结: render和redirect的区别: 1 if render的页面需要模板语言渲染,需要的将数据库的数据加载到html,那么所有的这一部分 # 除了写在yuan_back的视图函数中,必须还要写在login中,代码重复,没有解耦. 2 the most important: url没有跳转到/yuan_back/,而是还在/login/,所以当刷新后 # 又得重新登录.

 

Template

模板系统的介绍

不要将HTML被直接硬编码在 Python代码之中。

  • 对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。

  • Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。

  • 程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。

基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题。

 

python的模板:HTML代码+逻辑控制代码

 

模板支持的语法

变量(使用双大括号来引用变量)

语法格式:       {{var_name}}
python manange.py shell  (###进入该django项目的环境)
from django.template import Context, Template
t = Template(\'Hello, {{ name }}\')
for name in (\'John\', \'Julie\', \'Pat\'):
    print t.render(Context({\'name\': name}))

Django 模板大部分的解析工作都是在后台通过对简短正则表达式一次性调用来完成。 这和基于 XML 的模板引擎形成鲜明对比。

 

{% if %} 的使用 

{% if %}标签计算一个变量值,如果是“true”,即它存在、不为空并且不是false的boolean值,系统则会显示{% if %}和{% endif %}间的所有内容

{% if num >= 100 and 8 %}

    {% if num > 200 %}
        <p>num大于200</p>
    {% else %}
        <p>num大于100小于200</p>
    {% endif %}

{% elif num < 100%}
    <p>num小于100</p>

{% else %}
    <p>num等于100</p>

{% endif %}



{% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量
{% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的:

{% if obj1 and obj2 or obj3 %} 

{% for %}的使用

{% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容

<ul>
{% for obj in list %}
    <li>{{ obj.name }}</li>
{% endfor %}
</ul>


#在标签里添加reversed来反序循环列表:

    {% for obj in list reversed %}
    ...
    {% endfor %}

#{% for %}标签可以嵌套:

    {% for country in countries %}
        <h1>{{ country.name }}</h1>
        <ul>
         {% for city in country.city_list %}
            <li>{{ city }}</li>
         {% endfor %}
        </ul>
    {% endfor %}


#系统不支持中断循环,系统也不支持continue语句,{% for %}标签内置了一个forloop模板变量,
#这个变量含有一些属性可以提供给你一些关于循环的信息

1,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1:

    {% for item in todo_list %}
        <p>{{ forloop.counter }}: {{ item }}</p>
    {% endfor %}
2,forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0
3,forloop.revcounter
4,forloop.revcounter0
5,forloop.first当第一次循环时值为True,在特别情况下很有用:
    {% for object in objects %}   
         {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}   
         {{ object }}   
        </li>  
    {% endfor %}  
    
# 富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了
# 如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它
# Django会在for标签的块中覆盖你定义的forloop变量的值
# 在其他非循环的地方,你的forloop变量仍然可用


#{% empty %}

{{li }}
      {%  for i in li %}
          <li>{{ forloop.counter0 }}----{{ i }}</li>
      {% empty %}
          <li>this is empty!</li>
      {% endfor %}

#         [11, 22, 33, 44, 55]
#            0----11
#            1----22
#            2----33
#            3----44
#            4----55
例子

extend模板继承

到目前为止,我们的模板范例都只是些零星的 HTML 片段,但在实际应用中,你将用 Django 模板系统来创建整个 HTML 页面。 这就带来一个常见的 Web 开发问题: 在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码?Django 解决此类问题的首选方法是使用一种优雅的策略—— 模板继承 。

本质上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。

可以对那些不同 的代码段进行定义,而不是 共同 代码段。

第一步是定义 基础模板,该框架之后将由子模板所继承。 以下是我们目前所讲述范例的基础模板:

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    {% block content %}{% endblock %}
    {% block footer %}
    <hr>
    <p>Thanks for visiting my site.</p>
    {% endblock %}
</body>
</html>
View Code

子模板的作用就是重载、添加或保留那些块的内容。 

我们使用模板标签: {% block %} 。 所有的 {% block %} 标签告诉模板引擎,子模板可以重载这些部分。 每个{% block %}标签所要做的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。

现在我们已经有了一个基本模板,我们可以修改 current_datetime.html 模板来 使用它:

{% extends "base.html" %}
 
{% block title %}The current time{% endblock %}
 
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}

每个模板只包含对自己而言 独一无二 的代码。

以上是关于框架--1django的主要内容,如果未能解决你的问题,请参考以下文章

短视频学习 - 1Django运维实战

Django

Django

1django 简介与部署

text 来自Codyhouse框架的Browserlist片段源代码

使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段