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})
原文地址:https://www.cnblogs.com/hzhcdhm/p/8290122.html