Python之路,Day14 - It's time for Django
本节内容
Django流程介绍
Django url
Django view
Django models
Django template
Django form
Django admin
Django流程介绍
Django URL
Example
Here’s a sample URLconf:
1
2
3
4
5
6
7
8
9
10
|
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),
] |
Notes:
- To capture a value from the URL, just put parenthesis around it.
- There’s no need to add a leading slash, because every URL has that. For example, it’s
^articles
, not^/articles
. - The
'r'
in front of each regular expression string is optional but recommended. It tells Python that a string is “raw” – that nothing in the string should be escaped. See .
Example requests:
- A request to
/articles/2005/03/
would match the third entry in the list. Django would call the functionviews.month_archive(request, '2005', '03')
. -
/articles/2005/3/
would not match any URL patterns, because the third entry in the list requires two digits for the month. -
/articles/2003/
would match the first pattern in the list, not the second one, because the patterns are tested in order, and the first one is the first test to pass. Feel free to exploit the ordering to insert special cases like this. Here, Django would call the functionviews.special_case_2003(request)
-
/articles/2003
would not match any of these patterns, because each pattern requires that the URL end with a slash. -
/articles/2003/03/03/
would match the final pattern. Django would call the functionviews.article_detail(request, '2003', '03', '03')
.
Named groups
The above example used simple, non-named regular-expression groups (via parenthesis) to capture bits of the URL and pass them as positional arguments to a view. In more advanced usage, it’s possible to use named regular-expression groups to capture URL bits and pass them as keyword arguments to a view.
In Python regular expressions, the syntax for named regular-expression groups is (?P<name>pattern)
, where name
is the name of the group and pattern
is some pattern to match.
Here’s the above example URLconf, rewritten to use named groups:
1
2
3
4
5
6
7
8
9
10
|
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),
] |
This accomplishes exactly the same thing as the previous example, with one subtle difference: The captured values are passed to view functions as keyword arguments rather than positional arguments. For example:
- A request to
/articles/2005/03/
would call the functionviews.month_archive(request, year='2005',month='03')
, instead ofviews.month_archive(request, '2005', '03')
. - A request to
/articles/2003/03/03/
would call the functionviews.article_detail(request, year='2003',month='03', day='03')
.
In practice, this means your URLconfs are slightly more explicit and less prone to argument-order bugs – and you can reorder the arguments in your views’ function definitions. Of course, these benefits come at the cost of brevity; some developers find the named-group syntax ugly and too verbose.
What the URLconf searches against
The URLconf searches against the requested URL, as a normal Python string. This does not include GET or POST parameters, or the domain name.
For example, in a request to https://www.example.com/myapp/
, the URLconf will look for myapp/
.
In a request to https://www.example.com/myapp/?page=3
, the URLconf will look for myapp/
.
The URLconf doesn’t look at the request method. In other words, all request methods – POST
, GET
, HEAD
, etc. – will be routed to the same function for the same URL.
Captured arguments are always strings
Each captured argument is sent to the view as a plain Python string, regardless of what sort of match the regular expression makes. For example, in this URLconf line:
1 |
url(r '^articles/(?P<year>[0-9]{4})/$' , views.year_archive),
|
- ...the
year
argument passed toviews.year_archive()
will be a string, - not an integer, even though the
[0-9]{4}
will only match integer strings. -
Including other 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 itself. It includes a number of other URLconfs:
12345678from
django.conf.urls
import
include, url
urlpatterns
=
[
# ... snip ...
url(r
'^community/'
, include(
'django_website.aggregator.urls'
)),
url(r
'^contact/'
, include(
'django_website.contact.urls'
)),
# ... snip ...
]
Note that the regular expressions in this example don’t have a
$
(end-of-string match character) but do include a trailing slash. Whenever Django encountersinclude()
(), it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.Another possibility is to include additional URL patterns by using a list of instances. For example, consider this URLconf:
12345678910111213141516from
django.conf.urls
import
include, url
from
apps.main
import
views as main_views
from
credit
import
views as credit_views
extra_patterns
=
[
url(r
'^reports/$'
, credit_views.report),
url(r
'^reports/(?P<id>[0-9]+)/$'
, credit_views.report),
url(r
'^charge/$'
, credit_views.charge),
]
urlpatterns
=
[
url(r
'^$'
, main_views.homepage),
url(r
'^help/'
, include(
'apps.help.urls'
)),
url(r
'^credit/'
, include(extra_patterns)),
]
In this example, the
/credit/reports/
URL will be handled by thecredit_views.report()
Django view.This can be used to remove redundancy from URLconfs where a single pattern prefix is used repeatedly. For example, consider this URLconf:
123456789from
django.conf.urls
import
url
from
.
import
views
urlpatterns
=
[
url(r
'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/history/$'
, views.history),
url(r
'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/edit/$'
, views.edit),
url(r
'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/discuss/$'
, views.discuss),
url(r
'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/permissions/$'
, views.permissions),
]
We can improve this by stating the common path prefix only once and grouping the suffixes that differ:
1234567891011from
django.conf.urls
import
include, url
from
.
import
views
urlpatterns
=
[
url(r
'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/'
, include([
url(r
'^history/$'
, views.history),
url(r
'^edit/$'
, views.edit),
url(r
'^discuss/$'
, views.discuss),
url(r
'^permissions/$'
, views.permissions),
])),
]
Passing extra options to view functions
URLconfs have a hook that lets you pass extra arguments to your view functions, as a Python dictionary.
The function can take an optional third argument which should be a dictionary of extra keyword arguments to pass to the view function.
For example:
123456from
django.conf.urls
import
url
from
.
import
views
urlpatterns
=
[
url(r
'^blog/(?P<year>[0-9]{4})/$'
, views.year_archive, {
'foo'
:
'bar'
}),
]
In this example, for a request to
/blog/2005/
, Django will callviews.year_archive(request, year='2005',foo='bar')
.This technique is used in the to pass metadata and options to views.
Dealing with conflicts
It’s possible to have a URL pattern which captures named keyword arguments, and also passes arguments with the same names in its dictionary of extra arguments. When this happens, the arguments in the dictionary will be used instead of the arguments captured in the URL.
Passing extra options to
include()
Similarly, you can pass extra options to . When you pass extra options to
include()
, each line in the included URLconf will be passed the extra options.For example, these two URLconf sets are functionally identical:
Set one:
123456789101112131415# main.py
from
django.conf.urls
import
include, url
urlpatterns
=
[
url(r
'^blog/'
, include(
'inner'
), {
'blogid'
:
3
}),
]
# inner.py
from
django.conf.urls
import
url
from
mysite
import
views
urlpatterns
=
[
url(r
'^archive/$'
, views.archive),
url(r
'^about/$'
, views.about),
]
Set two:
123456789101112131415# main.py
from
django.conf.urls
import
include, url
from
mysite
import
views
urlpatterns
=
[
url(r
'^blog/'
, include(
'inner'
)),
]
# inner.py
from
django.conf.urls
import
url
urlpatterns
=
[
url(r
'^archive/$'
, views.archive, {
'blogid'
:
3
}),
url(r
'^about/$'
, views.about, {
'blogid'
:
3
}),
]
Note that extra options will always be passed to every line in the included URLconf, regardless of whether the line’s view actually accepts those options as valid. For this reason, this technique is only useful if you’re certain that every view in the included URLconf accepts the extra options you’re passing.
Django Views
最简单的返回一个字符串形式的view
123456from
django.http
import
HttpResponse
def
my_view(request):
if
request.method
=
=
'GET'
:
# <view logic>
return
HttpResponse(
'result'
)
如果想直接返回一个html文档
1234567from
django.shortcuts
import
render,HttpResponse
# Create your views here.
def
test_view(request):
return
render(request,
'index.html'
)
Django Models
django 本身提供了非常强大易使用的ORM组件,并且支持多种数据库,如sqllite,mysql,progressSql,Oracle等,当然最常用的搭配还是mysql,要启用orm,先要配置好连接数据 的信息
在你创建的project目录下编辑settings.py
12345678910DATABASES
=
{
'default'
: {
'ENGINE'
:
'django.db.backends.mysql'
,
'NAME'
:
'OldboyWebsite'
,
#确保此数据库已存在
'HOST'
:'',
'PORT'
:'',
'USER'
:
'root'
,
'PASSWORD'
:''
}
}
下面要开始学习Django ORM语法了,为了更好的理解,我们来做一个基本的 书籍/作者/出版商 数据库结构。 我们这样做是因为 这是一个众所周知的例子,很多SQL有关的书籍也常用这个举例。
我们来假定下面的这些概念、字段和关系:
一个作者有姓,有名及email地址。
出版商有名称,地址,所在城市、省,国家,网站。
书籍有书名和出版日期。 它有一个或多个作者(和作者是多对多的关联关系[many-to-many]), 只有一个出版商(和出版商是一对多的关联关系[one-to-many],也被称作外键[foreign key])
1234567891011121314151617181920from
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
=
60
)
state_province
=
models.CharField(max_length
=
30
)
country
=
models.CharField(max_length
=
50
)
website
=
models.URLField()
class
Author(models.Model):
first_name
=
models.CharField(max_length
=
30
)
last_name
=
models.CharField(max_length
=
40
)
email
=
models.EmailField()
class
Book(models.Model):
title
=
models.CharField(max_length
=
100
)
authors
=
models.ManyToManyField(Author)
publisher
=
models.ForeignKey(Publisher)
publication_date
=
models.DateField()
更多models field 字段:https://docs.djangoproject.com/en/1.9/ref/models/fields/
每个模型相当于单个数据库表,每个属性也是这个表中的一个字段。 属性名就是字段名,它的类型(例如CharField )相当于数据库的字段类型 (例如 varchar )。例如, Publisher 模块等同于下面这张表(用PostgreSQL的 CREATE TABLE 语法描述):
123456789CREATE
TABLE
"books_publisher"
(
"id"
serial
NOT
NULL
PRIMARY
KEY
,
"name"
varchar
(30)
NOT
NULL
,
"address"
varchar
(50)
NOT
NULL
,
"city"
varchar
(60)
NOT
NULL
,
"state_province"
varchar
(30)
NOT
NULL
,
"country"
varchar
(50)
NOT
NULL
,
"website"
varchar
(200)
NOT
NULL
);
模型安装
完成这些代码之后,现在让我们来在数据库中创建这些表。 要完成该项工作,第一步是在 Django 项目中 激活这些模型。 将上面的模型所在的app (此例子app是books) 添加到配置文件的已安装应用列表中即可完成此步骤。
再次编辑 settings.py 文件, 找到 INSTALLED_APPS 设置。 INSTALLED_APPS 告诉 Django 项目哪些 app 处于激活状态。 缺省情况下如下所示:
1234567INSTALLED_APPS
=
(
'django.contrib.auth'
,
'django.contrib.contenttypes'
,
'django.contrib.sessions'
,
'django.contrib.sites'
,
'books'
,
)
使数据库按照模型的配置生成表结构
12345678910111213Jies-MacBook-Air:s12django jieli$ python manage.py makemigrations
#生成同步纪录
Migrations
for
'app01'
:
0001_initial.py:
- Create model Author
- Create model Book
- Create model Publisher
- Add field publisher to book
Jies-MacBook-Air:s12django jieli$ python manage.py migrate
#开始同步
Operations to perform:
Apply all migrations: admin, contenttypes, app01, auth, sessions
Running migrations:
Rendering model states... DONE
Applying app01.0001_initial... OK
基本数据访问
一旦你创建了模型,Django自动为这些模型提供了高级的Python API。 运行 python manage.py shell 并输入下面的内容试试看:
123456789101112>>>
from
books.models
import
Publisher
>>> p1
=
Publisher(name
=
'Apress'
, address
=
'2855 Telegraph Avenue'
,
... city
=
'Berkeley'
, state_province
=
'CA'
, country
=
'U.S.A.'
,
... website
=
'http://www.apress.com/'
)
>>> p1.save()
>>> p2
=
Publisher(name
=
"O'Reilly"
, address
=
'
10
Fawcett St.',
... city
=
'Cambridge'
, state_province
=
'MA'
, country
=
'U.S.A.'
,
... website
=
'http://www.oreilly.com/'
)
>>> p2.save()
>>> publisher_list
=
Publisher.objects.
all
()
>>> publisher_list
[<Publisher: Publisher
object
>, <Publisher: Publisher
object
>]
这里有一个值得注意的地方,在这个例子可能并未清晰地展示。 当你使用Django modle API创建对象时Django并未将对象保存至数据库内,除非你调用`` save()`` 方法:
赞 (0)打赏 微信扫一扫相关文章:
-
-
CloudGeek读源码系列-cache2go源码解析(二)
0、写在最前面 What:《cache2go的源码解析》会分为(一)(二)两讲,内容包括整个项目的所有功能代码和例子程序。 上一讲《CloudGee... [阅读全文] -
经典的策略模式案例 问题描述 使用“策略”设计模式处理订单折扣的 UML 类图 定义一系列算法,把它们一一封装起来,并且使它们可以相互替换。本模式使... [阅读全文]
-
list -> [] list是python内置的有序集合数据类型,可随时添加和删除元素。例如:创建一个动物的列表: len()函数可以获取l... [阅读全文]
-
1.后代选择器和子元素选择器之间的区别? 1.1后代选择器使用空格作为连接符号 子元素选择器使用>作为连接符号 1.2后代选择器会选中指定标签... [阅读全文]
-
1.id和class的区别? id相当于人的身份证不可以重复 class相当于人的名称可以重复 1.2 一个HTML标签只能绑定一个id名称 一个H... [阅读全文]
-
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
上一篇: 多个苹果iCloud服务遭遇服务中断
下一篇: “机器换人”时代来了 工人何去何从
推荐阅读
-
Python之路【第二十七篇】:web服务器django
-
Python之路【第二十九篇】:django ORM模型层
-
Python之路【第二十八篇】:django视图层、模块层
-
系统策略禁止安装python_Python之路:Centos7.3系统下安装Django2.2
-
Python之路,Day14 - It's time for Django
-
Python之路【第二十七篇】:web服务器django
-
Python之路【第二十九篇】:django ORM模型层
-
Python之路【第二十八篇】:django视图层、模块层
-
k8s集群部署python+django项目
-
Python之路,Day14 - It's time for Django
发表评论