zoukankan      html  css  js  c++  java
  • web框架django 1

    Python 的 web 框架有 Django、Tornado、Flask 等多种,Django 相较于其他 web 框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session 等诸多功能。

    一、基本配置

    1、创建 django 程序

    •  通过终端命令来创建

    2、程序目录

              

    3、配置文件

    3.1 数据库

    django 默认配置数据库

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }

    以下将 django 数据库修改为 mysql

    DATABASES = {
        'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'dbname',
        'USER': 'root',
        'PASSWORD': 'xxx',
        'HOST': 'localhost',  # 连接本地的数据库,也可以不写,默认是本地
        'PORT': 3306,
        }
    }

    由于 Django 内部连接 Mysql 时使用的是Mysqldb 模块,而 Python3 中还没有这个模块,所以需要使用pymysql 来代替

    如下设置放置的与 project 同名的配置的 __init__.py 文件中

    import pymysql
    pymysql.install_as_MySQLdb()

    3.2 模板

    TEMPLATE_DIRS = (
            os.path.join(BASE_DIR,'templates'),
        )

    3.3 静态文件

    STATICFILES_DIRS = (
            os.path.join(BASE_DIR,'static'),
        )

    3.4 新增APP

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
        'app02',
    ]

    二、Django 框架介绍

    Django 框架简介

    MVC 框架和MTV框架0(了解即可)

    MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基础部分:模型(Model)、视图(View)和控制器(Controller),具有耦合性低、重用性高、生命周期成本低等优点。

     

    想要更详细的了解MVC模式?>>>>点我

     Django 框架的不同之处在于它拆分的三部分为:Model(模型)、Template(模板)和View(视图),也就是MTV框架。

    1、Django 的 MTV 模式

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

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

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

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

    2、Django 框架图示

    APP

     一个Django 项目可以分为很多个APP,用来隔离不同功能模块的代码

    1、命令行创建

    python manage.py startapp app01

    2、使用 pycharm 创建

    在下方弹出的命令窗口输入:

    startapp app01  # 其中app01只是给创建的app取的名字,可以是其他的例如:login等名字 

    三、路由系统

    URL配置(URLconf)就像 Django 所支撑网站的目录。它的本质是URL 与要为该 URL 调用的视图函数之间的映射表;

    你就是以这种方式告诉 Django,对于这个 URL 调用这段代码,对于那个 URL 调用哪段代码。

    URLconf 配置

    1、基本格式:

    from django.conf.urls import url
    
    urlpatterns = [
         url (正则表达式, view视图函数, 参数别名),   
    ]
    
    
    参数说明:
        1、正则表达式:一个正则表达式字符串
        2、views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
        3、参数:可选的要传递给视图函数的默认参数(字典的形式)
        4、别名:一个可选的 name 参数

    注意:在Django 2.0 版本中的路由系统已经替换成下面的写法了(官方文档):

    from django.urls import path
    
    urlpatterns = [
        path('articles/2003/', views.special_case_2003),
        path('artices/<int:year>/', views.year_archive),
        path('artices/<int:year>/<int:month>/', views.month_archive),
        path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail ),
    ]

    正则表达式详解

    1、基本配置

    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),
    ]

    注意事项:

      1、urlpatterns 中元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。

      2、若要从URL 中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。

      3、不需要添加一个前导的反斜杠,因为每个URL都有。例如:应该是 ^articles 而不是 ^/articles。

      4、每个正则表达式前面的 “r” 是可选的,但是建议加上。

    2、补充说明

    # 是否开启 URL 访问地址后面不为/ 跳转至带有 / 的路径的配置项
    APPEND_SLASH = True

    Django setting.py 配置文件中默认没有 APPEND_SLASH 这个参数,但Django 默认这个参数为 APPEND_SLASH = True。其作用就是自动在网址的结尾加上 “/”。

    其结果就是:
    我们定义了urls.py:

    from django.conf.urls import url
    from app01 import views
    
    urlpatterns = [
        url(r"^blog/$", views.blog),
    ]

    访问 http://www.example.com/blog 时,默认将网址自动转换成 http://www/example/com/blog/。

    如果在 setting,py 中设置了 APPEND_SLASH = False,此时我们再请求http://www.example.com/blog 时由于不会在后面自动添加一个/ 则不符合正则表达式,就会提示找不到页面。

    分组命名匹配                                                                                     

    上面的示例使用简单的正则表达式分组匹配(通过圆括号)来捕获URL中的值并以位置参数形式传递给视图。

    在更高级的使用法中,可以使用分组命名匹配的正则表达式组来捕获URL中的值并以关键字参数形式传递给视图。

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

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

    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        url(r'^articles/2003/$', views.special_case_2003),
        url(r'^artical/(?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),
        

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

    例如:针对 url /articles/2017/12/ 相当于按以下方式调用视图函数:

    views.month_archive(request, year= "2017", month="12")

    在实际应用中,使用分组命名匹配的方式可以让你的 URLconf 更加明晰且不容易产生参数顺序问题的错误,但是有些开发人员则认为分组命名组语法太丑陋、繁琐。

    1、URLconf 匹配的位置

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

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

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

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

    2、捕获的参数永远是字符串

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

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

    其中传递到函数 views.year_archive() 中的 year 参数永远是一个字符串类型。

    3、视图函数中指定默认值

    # urls.py 中
    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),
    ]
    
    
    # views.py 中,可以为num 指定默认值
    
    def page(request, num = '1'):
        pass

    4、include 其他的 URLconfs

    #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文件
    ]

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

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

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

    例如:

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
    ]

    在这个例子中,对于 /blog/2005/ 请求,Django 将调用views.year_archive(request, year="2005", foo="bar")。

    这个技术在Syndication 框架中使用,来传递元数据和选项给视图。

    命名URL和URL反向解析

     在使用Django 项目时,一个常见的需求是获得URL的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的 URL等)或者用于处理服务器端的导航(重定向等)。

    人们强烈希望不要硬编码这些 URL(费力、不可扩展且容易产生错误)或者设计一种与 URLconf 毫不相关的专门的 URL 生成机制,因为这样容易导致一定程度上产生过期的 URL。

     换句话讲,需要的是一个DRY机制。除了其他点,它还允许设计的URL可以自动更新而不用遍历项目的源代码来搜索并替换过期的URL。

    获取一个URL最开始想到的信息是处理它的视图的标识(例如名字),查找正确的URL的其它必要的信息有视图参数的类型(位置参数、关键字参数)和值。

    Django提供一个方法是让 URL 进行映射,这是URL设计唯一的地方。你填充你的URLconf,然后可以双向使用它:

    • 根据用户/浏览器发起的URL请求,它调用正确的Django视图,并从 URL 中提取它的参数需要的值。
    • 根据Django视图的标识和将要传递给它的参数的值,获取与之关联的 URL。

      第一方式是外面在前面的章节中一直讨论的方法。第二种方式叫做反向解析 URL、反向 URL匹配、反向 URL查询或者简单的URL反查。

    在需要URL的地方,对于不同层级,Django提供不同的工具用于 URL反查:

    • 在模板中:使用URL模板标签
    • 在Python代码中:使用django.core.urlresolvers.reverse() 函数。
    • 在更高层的与处理Django模型实例相关的代码中:使用get_absolute_url() 方法。

    简单的说就是可以给我们的 URL 匹配规则起个别名,一个 URL 匹配模式起一个名字。这样以后就不需要写死 URL代码了,只需要通过名字来调用当前的 URL。

    举例:

    url(r'^home', views.home, name='home'),  # 给我的url匹配模式起名为 home
    url(r'^index/(d*)', views.index, name='index'),  # 给我的url匹配模式起名为index
    
    # 给 URL 起别名的话之后不管前面的views.index 或 views.home 怎样改变,在后面模板中都使用的是name的值,不会有任何影响

    这样模板里面可以这样引用:

    {% url "home" %}
    {% url "index" %}

    在views函数中可以这样引用:

    from django.urls import reverse
    
    reverse("index")
    
    
    
    # 在urls.py 文件中如果是
    url(r'^index/(d*)', views.index, name='index', {'key': 'value'}),
    的时候写成
    
    reverse("index", args=(2018,))

    例子:

    考虑下面的 URLconf:

    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        # ...
        url(r'^articles/([0-9]{4})/$', views.year_archive, name = 'news-year-archive'),
        # ...
    ]

    根据这里的设计,某一年nnnn对应的归档的URL是 /articles/nnnn/

    可以在模板的代码中使用下面的方法获得它们:

    <a href="{% url 'news-year-archive' 2012 %}">2012 Achive</a>
    
    
    <ul>
    {% for yearvar in year_list %}
    <li>
        <a href="{% url 'news-year-archive' yearvar %}">{{yearvar}} Archive</a>
    </li>
    {% endfor %}
    </ul>

    在Python代码中,这样使用:

    from django.urls import reverse
    from django.shortcuts import redirect
    
    def redirect_to_year(request):
        # ...
        year = 2017
        # ...
        return redirect(reverse('news-year-archive', args=(years, )))

    如果出于某种原因决定要按年归档文章,发布的URL就应该调整一下,那么就只需要修改 URLconf 中的内容。

    在某些场景中,一个视图是通用的,所以在 URL和视图之间存在多对一的关系。对于这些情况,当反查 URL时,只有视图的名字还不够。

    注意:

    为了完成上面例子中的 URL 反查,你将需要使用命名的URL模式。URL的名称使用的字符串可以包含任何你喜欢的字符。不只限制在合法的Python名称。

    当命名你的 URL 模式时,请确保使用的名称不会与其它应用中的名称冲突。如果你的 URL 模式叫做 comment,而另外一个应用中也有一个同样的名称,当你在模板中使用这个名称的时候不能保证将插入哪个 URL。

    在URL名称中加上一个前缀,比如应用的名称,将减少冲突的可能。我们建议使用 myapp-comment 而不是 comment

    1、单一路由对应

    url(r'^index$', views.index),

    2、基于正则的路由

    #  $
    url(r'^index/(d{4})$',views.index)
     
    #无命名分组
    url(r'^index/(d{4})/(d{2})',views.index)
     
    #有命名分组
    url(r'^index/(?P<year>d{4})/(?P<month>d{2})',views.index)                                                                                                                                                               

    有无命名分组演示

    ############################无命名
    
    #相当于传参数 
    
    url(r'^index/(d{4})',views.index)
        
        def index(request,arg):
            return HttpResponse(arg)    
    
    #url访问http://127.0.0.1:8000/index/1113
    
    #接受两个参数
    
    url(r'^index/(d{4})/(d{2})',views.index)
    
        def index(request,arg,arg1):
            return HttpResponse("year: %s month: %s"%(arg,arg1))
    
    #url访问http://127.0.0.1:8000/index/2017/06
        year: 2017 month: 06
    
    
    
    ############################有命名
    url(r'^index/(?P<year>d{4})/(?P<month>d{2})',views.index)
    
        def index(request,year,month):
            return HttpResponse("year: %s month: %s"%(year,month))
    
    #url访问http://127.0.0.1:8000/index/2017/06
        year: 2017 month: 06  

    3、添加额外的参数

    url(r'^manage/(?P<name>w*)', views.manage,{'id':333}),

    4、为路由映射设置名称及使用

    #应用一:
    url(r'^index',views.index,name="arg")
     
    {{ url "arg" }}     匹配index
    {{ url "arg" i}}
     
    #应用二:
    reverse反向获取url
    
    ##############根据url反生成名字
    from django.shortcuts import reverse
    
    url(r'^index',views.index,name="arg")
    
    def index(request):
        v = reverse("arg")
        print(v)
        return HttpResponse()
    
     #用户访问http://127.0.0.1:8000/index
     /index
    
    
    ##############根据url改变url
    
    url(r'^index/(d+)/',views.index,name="n1")
    
    def index(request,xx):
    
        v = reverse('n1',args=(1,))
        print(v)
        return HttpResponse("...")
    
     #访问http://127.0.0.1:8000/index/222/
     /index/1/
    url(r'^home', views.home, name='h1'),
    url(r'^index/(d*)', views.index, name='h2'),

    设置名称之后,可以在不同的地方调用,如:

    • 模板中使用生成URL    {% url "h2" 2012 %}
    • 函数中使用生成URL    reverse("h2", args = (2012,))    路径: django.url.reverse
    • Model 中使用获取URL   自定义 get_absolute_url() 方法
    class NewType(models.Model):
        caption = models.CharField(max_length=16)
    
    
        def get_absolute_url(self):
            """
            为每个对象生成一个URL
            应用:在对象列表中生成查看详细的URL,使用此方法即可!!!
            :return:
            """
            # return '/%s/%s' % (self._meta.db_table, self.id)
            #
            from django.urls import reverse
            return reverse('NewType.Detail', kwargs={'nid': self.id})

    获取请求配置成功的URL信息:request.resolver_match

    5、根据app 对路由规则进行分发

    url(r'^app01/',include("app01.urls"))
    url(r'^app02/',include("app02.urls"))
      
    #没有匹配成功,返回默认页面
    url(r'^',include("views.default")) 

    6、命名空间

     6.1 project.urls.py

    from django.conf.urls import url, include
    
    urlpatterns = [
        url(r'^a/', include('app01.urls', namespace='author-polls')),
        url(r'^b/', include('app01.urls', namespace='publisher-polls')),
    ]

    6.2 app01.urls.py

    from django.conf.urls import url
    from app01 import views
    
    app_name='app01'
    urlpatterns = [
        url(r'^(?P<pk>d)/$', views.detail, name = 'detail'),
    ]

    6.3 模板中的引用:

    {% url 'app01:detail' pk=12 pp=99 %}

    6.4 views 中的函数引用:

    v = reverse('app01:detail', kwargs={'pk': 11})
  • 相关阅读:
    #pragma 预处理指令
    C++类继承中的构造函数和析构函数 调用顺序
    static_cast与dynamic_cast转换 最简单的理解
    std::map的insert和下标[]访问
    C++有没有string转化int的函数,怎样转换
    c++中在一个类中定义另一个只有带参数构造函数的类的对象
    c++二进制文件的读写
    C++ 包含头文件 和 宏的使用 和 条件编译
    C++ 前置声明 和 包含头文件 如何选择
    C语言 gets()和scanf()函数的区别
  • 原文地址:https://www.cnblogs.com/hzhcdhm/p/8290122.html
Copyright © 2011-2022 走看看