django book
1:生成一个项目:
django‐admin.py startproject mysite
2:启动项目:mysite
python manage.py runserver 只限本机访问。
python manage.py runserver 0.0.0.0:8000。允许其他的电脑通过IP访问我们的项目。
3:视图:view.py
视图函数中,必须第一个参数为request.他是触发视图和用户请求信息的实例是HTTPrequest的实例对象。名字可以不是他,随便起名字,但是第一个参数必须是他。
4:url.py
我们写的url都是以'/'结尾,当我们申请的url不包含'/'的时候,默认会找相同的字眼且包含'/'的url。比如:/go 默认转发到/go/。
默认值: True
设为 True 时,如果请求的URL与URLconf中的任何一个URL模式都不匹配,且URL并没有以斜杠结尾,那么Django就会重定向到以斜杠结尾的相同网址。 要注意的是,重定向可能会导致某些POST请求所提交的数据丢失。
APPEND_SLASH 设置项只有在安装了 CommonMiddleware 的情况下才会生效。 (详见 Middleware)。 也可参见PREPEND_WWW 。
这就要求在post url中必须要'/'结尾。
url正则表达式。
设置默认不存在url访问的默认网页:
'^$', my_homepage_view
django 项目的启动一切的开始的源于 setting.py文件。通过:
ROOT_URLCONF = 'orm.urls'
找到我们的路由系统。
5:一个url的访问,整个django走的流程。
1. 进来的请求转入/hello/.
2. Django通过在ROOT_URLCONF配置来决定根URLconf.
3. Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目。
4. 如果找到匹配,将调用相应的视图函数
5. 视图函数返回一个HttpResponse
6. Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来
重要知识点:
之前我们在写字符串的时候,比如系统路径的时候,尤其是winow的路径的时候,window路径是:\反斜杠,在python中\表示转义的意思。
这时候我们需要用r 'string'来表示这个字符串是原始字符串,里面的反斜杠\不需要转义!!!
如果不加r或者反斜杠的时候会被转义!!!
另外一个重点,正则表达式字符串的开头字母“r”。 它告诉Python这是个原始字符串,不需要处理里面的反
斜杠(转义字符)。 在普通Python字符串中,反斜杠用于特殊字符的转义。比如n转义成一个换行符。 当你用
r把它标示为一个原始字符串后,Python不再视其中的反斜杠为转义字符。也就是说,“n”是两个字符
串:“”和“n”。由于反斜杠在Python代码和正则表达式中有冲突,因此建议你在Python定义正则表达式时
都使用原始字符串。 从现在开始,本文所有URL模式都用原始字符串
简单的主动的抛出404错误。
1 from django.http import Http404, HttpResponse 2 import datetime 3 def hours_ahead(request, offset): 4 try: 5 offset = int(offset) 6 except ValueError: 7 raise Http404() 8 dt = datetime.datetime.now() + datetime.timedelta(hours=offset) 9 html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt) 10 return HttpResponse(html)
6:模板
注意的在模板中 字典的或者value的值时候用句点 .而 表示索引的时候用[index]
1 最后,句点也可用于访问列表索引,例如: 2 >>> from django.template import Template, Context 3 >>> t = Template('Item 2 is {{ items.2 }}.') 4 >>> c = Context({'items': ['apples', 'bananas', 'carrots']}) 5 >>> t.render(c) 6 u'Item 2 is carrots.' 7 不允许使用负数列表索引。 像 {{ items.‐1 }} 这样的模板变量将会引发`` TemplateSyntaxError``
Python 列表类型
一点提示: Python的列表是从0开始索引。 第一项的索引是0,第二项的是1,依此类推。
句点查找规则可概括为: 当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找:
字典类型查找 (比如 foo["bar"] )
属性查找 (比如 foo.bar )
方法调用 (比如 foo.bar() )
列表类型索引查找 (比如 foo[bar]
在模板调用的时候,如果一个变量无效,默认情况下,如果一个变量不存在,模板系统会把它展示为空字符串,不做任何事情来表示失败。
>>> from django.template import Template, Context >>> t = Template('Your name is {{ name }}.') >>> t.render(Context()) u'Your name is .' >>> t.render(Context({'var': 'hello'})) u'Your name is .' >>> t.render(Context({'NAME': 'hello'})) u'Your name is .' >>> t.render(Context({'Name': 'hello'})) u'Your name is .'
系统静悄悄地表示失败,而不是引发一个异常,因为这通常是人为错误造成的。 这种情况下,因为变量名有错
误的状况或名称, 所有的查询都会失败。 现实世界中,对于一个web站点来说,如果仅仅因为一个小的模板语
法错误而造成无法访问,这是不可接受的
当然最好是用if else 来判断变量是否有值 为最好的方法。
标签:
{% if %} 标签检查(evaluate)一个变量,如果这个变量为真(即,变量存在,非空,不是布尔值假),系统会
显示在 {% if %} 和 {% endif %} 之间的任何内容。
1 {% if today_is_weekend %} 2 <p>Welcome to the weekend!</p> 3 {% endif %} 4 {% else %} 标签是可选的: 5 {% if today_is_weekend %} 6 <p>Welcome to the weekend!</p> 7 {% else %} 8 <p>Get back to work.</p> 9 {% endif %}
以下的值 在模板中和python 中为false。
- 空列表[]
- 空元祖()
- 空字典{}
- 空字符串''
- 零值 0
- 特殊对象:None
- 对象False
{% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not ),
1 {% if athlete_list and coach_list %} 2 Both athletes and coaches are available. 3 {% endif %} 4 {% if not athlete_list %} 5 There are no athletes. 6 {% endif %} 7 {% if athlete_list or coach_list %} 8 There are some athletes or some coaches. 9 {% endif %} 10 {% if not athlete_list or coach_list %} 11 There are no athletes or there are some coaches. 12 {% endif %} 13 {% if athlete_list and not coach_list %} 14 There are some athletes and absolutely no coaches. 15 {% endif %}
if标签:
{% if %} 标签不允许在同一个标签中同时使用 and 和 or ,因为逻辑上可能模糊的,例如,如下示例是错误
的: 比如这样的代码是不合法的:
{% if athlete_list and coach_list or cheerleader_list %}
系统不支持用圆括号来组合比较操作。 如果你确实需要用到圆括号来组合表达你的逻辑式,考虑将它移到模板
之外处理,然后以模板变量的形式传入结果吧。 或者,仅仅用嵌套的 {% if %} 标签替换吧,就像这样:
1 {% if athlete_list %} 2 {% if coach_list or cheerleader_list %} 3 We have athletes, and either coaches or cheerleaders! 4 {% endif %} 5 {% endif %}
多次使用同一个逻辑操作符是没有问题的,但是我们不能把不同的操作符组合起来。 例如,这是合法的:
1 {% if athlete_list or coach_list or parent_list or teacher_list %}
一定要用 {% endif %} 关闭每一个 {% if %} 标签。
for标签:
{% for %} 允许我们在一个序列上迭代。 与Python的 for 语句的情形类似,循环语法是 for X in Y ,Y是要迭
代的序列而X是在每一个特定的循环中使用的变量名称。 每一次循环中,模板系统会渲染在 {% for %} 和
{% endfor %} 之间的所有内容
给标签增加一个 reversed 使得该列表被反向迭代:
1 {% for athlete in athlete_list reversed %} 2 ... 3 {% endfor %}
可以嵌套使用 {% for %} 标签:
1 {% for athlete in athlete_list %} 2 <h1>{{ athlete.name }}</h1> 3 <ul> 4 {% for sport in athlete.sports_played %} 5 <li>{{ sport }}</li> 6 {% endfor %} 7 </ul> 8 {% endfor %}
在执行循环之前先检测列表的大小是一个通常的做法,当列表为空时输出一些特别的提示。
1 {% if athlete_list %} 2 {% for athlete in athlete_list %} 3 <p>{{ athlete.name }}</p> 4 {% endfor %} 5 {% else %} 6 <p>There are no athletes. Only computer programmers.</p> 7 {% endif %}
因为这种做法十分常见,所以`` for`` 标签支持一个可选的`` {% empty %}`` 分句,通过它我们可以定义当列表
为空时的输出内容 下面的例子与之前那个等价:
1 {% for athlete in athlete_list %} 2 <p>{{ athlete.name }}</p> 3 {% empty %} 4 <p>There are no athletes. Only computer programmers.</p> 5 {% endfor %}
Django不支持退出循环操作。 如果我们想退出循环,可以改变正在迭代的变量,让其仅仅包含需要迭代的项
目。 同理,Django也不支持continue语句,我们无法让当前迭代操作跳回到循环头部
在每个`` {% for %}``循环里有一个称为`` forloop`` 的模板变量。这个变量有一些提示循环进度信息的属性。
forloop.counter 总是一个表示当前循环的执行次数的整数计数器。 这个计数器是从1开始的,所以在第一
次循环时 forloop.counter 将会被设置为1。有点类似python中enumerate()函数。
1 {% for item in todo_list %} 2 <p>{{ forloop.counter }}: {{ item }}</p> 3 {% endfor %}
1 forloop.counter0 类似于 forloop.counter ,但是它是从0计数的。 第一次执行循环时这个变量会被设置 2 为0。 3 forloop.revcounter 是表示循环中剩余项的整型变量。 在循环初次执行时 forloop.revcounter 将被设置 4 为序列中项的总数。 最后一次循环执行中,这个变量将被置1。 5 forloop.revcounter0 类似于 forloop.revcounter ,但它以0做为结束索引。 在第一次执行循环时,该变 6 量会被置为序列的项的个数减1。 7 forloop.first 是一个布尔值,如果该迭代是第一次执行,那么它被置为```` 在下面的情形中这个变量是 8 很有用的
1 {% for object in objects %} 2 {% if forloop.first %} 3 <li class="first"> 4 {% else %} 5 <li> 6 {% endif %} 7 {{ object }} 8 </li> 9 {% endfor %}
forloop.last 是一个布尔值;在最后一次执行循环时被置为True。 一个常见的用法是在一系列的链接之间
放置管道符(|)
1 {% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}
上面的模板可能会产生如下的结果
1 Link1 | Link2 | Link3 | Link4
另一个常见的用途是为列表的每个单词的加上逗号。
1 Favorite places: 2 {% for p in places %}{{ p }}{% if not forloop.last %}, {% endif %}{% endfor %}
标签:ifequal/ifnotequal
Django模板系统压根儿就没想过实现一个全功能的编程语言,所以它不允许我们在模板中执行Python的语句
(还是那句话,要了解更多请参看理念和限制小节)。 但是比较两个变量的值并且显示一些结果实在是个太常
见的需求了,所以Django提供了 {% ifequal %} 标签供我们使用。
{% ifequal %} 标签比较两个值,当他们相等时,显示在 {% ifequal %} 和 {% endifequal %} 之中所有的值。
下面的例子比较两个模板变量 user 和 currentuser :
例子:
1 {% ifequal user currentuser %} 2 <h1>Welcome!</h1> 3 {% endifequal %}
参数可以是硬编码的字符串,随便用单引号或者双引号引起来,所以下列代码都是正确的:
1 {% ifequal section 'sitenews' %} 2 <h1>Site News</h1> 3 {% endifequal %} 4 {% ifequal section "community" %} 5 <h1>Community</h1> 6 {% endifequal %}
和 {% if %} 类似, {% ifequal %} 支持可选的 {% else%} 标签:
1 {% ifequal section 'sitenews' %} 2 <h1>Site News</h1> 3 {% else %} 4 <h1>No News Here</h1> 5 {% endifequal %}
只有模板变量,字符串,整数和小数可以作为 {% ifequal %} 标签的参数。下面是合法参数的例子:
1 {% ifequal variable 1 %} 2 {% ifequal variable 1.23 %} 3 {% ifequal variable 'foo' %} 4 {% ifequal variable "foo" %}
其他任何类型,例如Python的字典类型、列表类型、布尔类型,不能用在 {% ifequal %} 中。 下面是些错误的
1 {% ifequal variable True %} 2 {% ifequal variable [1, 2, 3] %} 3 {% ifequal variable {'key': 'value'} %}
如果你需要判断变量是真还是假,请使用 {% if %} 来替代 {% ifequal %} 。
过滤器:我们一般给前端传递变量的时候,有时候我们需要额外的要求比如大小写等。
模板过滤器是在变量被显示前修改它的值的一个简单方法。 过滤器使用管道字符,
1 {{ name|lower }}
显示的内容是变量 {{ name }} 被过滤器 lower 处理后的结果,它功能是转换文本为小写。
多次过滤:
过滤管道可以被* 套接* ,既是说,一个过滤器管道的输出又可以作为下一个管道的输入,如此下去。 下面的例
子实现查找列表的第一个元素并将其转化为大写。
1 {{ my_list|first|upper }}
有些过滤器有参数。 过滤器的参数跟随冒号之后并且总是以双引号包含。 例如:
1 {{ bio|truncatewords:"30" }}
这个将显示变量 bio 的前30个词。
以下几个是最为重要的过滤器的一部分
addslashes : 添加反斜杠到任何反斜杠、单引号或者双引号前面。 这在处理包含JavaScript的文本时是非常
有用的。
date : 按指定的格式字符串参数格式化 date 或者 datetime 对象, 范例:
{{ pub_date|date:"F j, Y" }}
这个不清楚变量是什么格式才能被后面的date 没测试出来!!
小技巧:
- 在如果后端给前端模板出入的参数很多,如果我们定义字典的话,我们将会写很多的字段。我们可以用locals()内建函数来获取当前定义的局部变量。
前端显示的时候直接写变量既可。
1 def pub_date(request):
2 import time
3 pub_dat='2012-08-26 16:00:00'
4 a=2
5 print(pub_dat)
6 return render(request,'s1.html',locals())
模板语言:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 {{pub_dat}} 9 <div>{{ a }}</div> 10 </body> 11 </html>
include 模板标签:
{% include %} 。该标签允许在
(模板中)包含其它的模板的内容。 标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引
号硬编码的字符串。 每当在多个模板中出现相同的代码时,就应该考虑是否要使用 {% include %} 来减少重
复。
下面的例子包含了 includes/nav.html 模板的内容:
1 {% include 'includes/nav.html' %}
7:数据库操作:
当我们设置其他数据库的时候,我们在seting中设置完成之后,我们需要测试我们的连接串是否有效。这个时候需要用:python manage.py shell 该shell是以正确的命令django配置启用python 交互解释器的一种方法。
输入以下命令是否有效:
1 >>> from django.db import connection 2 >>> cursor = connection.cursor()
如果没有报错的话,那数据库的配置是正确的。
如下是数据库常见的报错。
1 C:\Users\Administrator\PycharmProjects\orm>python manage.py shell 2 Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32 3 Type "help", "copyright", "credits" or "license" for more information. 4 (InteractiveConsole) 5 >>> from django.db import connection 6 >>> cursor=connection.cursor
表示数据库设置没问题。
系统对app有一个约定: 如果你使用了Django的数据库层(模型),你 必须创建一个Django app。
模型必须存放在apps中。 因此,为了开始建造 我们的模型,我们必须创建一个新的app。
现在我们可以创建数据库表了。 首先,用下面的命令验证模型的有效性:
1 python manage.py validate
validate 命令检查你的模型的语法和逻辑是否正确。 如果一切正常,你会看到 0 errors found 消息。如果出
错,请检查你输入的模型代码。 错误输出会给出非常有用的错误信息来帮助你修正你的模型。
一旦你觉得你的模型可能有问题,运行 python manage.py validate 。 它可以帮助你捕获一些常见的模型定义
错误。
print对象的时候输出不是对象的列表而是我们想要的字段
1 from django.db import models 2 class Publisher(models.Model): 3 name = models.CharField(max_length=30) 4 address = models.CharField(max_length=50) 5 city = models.CharField(max_length=60) 6 state_province = models.CharField(max_length=30) 7 country = models.CharField(max_length=50) 8 website = models.URLField() 9 def __unicode__(self): 10 return self.name
就象你看到的一样, __unicode__() 方法可以进行任何处理来返回对一个对象的字符串表示。
如果需要以多个字段为标准进行排序(第二个字段会在第一个字段的值相同的情况下被使用到),使用多个参
数就可以了,如下:
1 >>> Publisher.objects.order_by("state_province", "address") 2 [<Publisher: Apress>, <Publisher: O'Reilly>]
我们还可以指定逆向排序,在前面加一个减号 ‐ 前缀:
1 >>> Publisher.objects.order_by("‐name") 2 [<Publisher: O'Reilly>, <Publisher: Apress>]
在,让我们来接触一个新的概念。 class Meta ,内嵌于 Publisher 这个类的定义中(如果 class Publisher
是顶格的,那么 class Meta 在它之下要缩进4个空格--按 Python 的传统 )。你可以在任意一个 模型 类中
使用 Meta 类,来设置一些与特定模型相关的选项。 在 附录B 中有 Meta 中所有可选项的完整参考,现在,我们
关注 ordering 这个选项就够了。 如果你设置了这个选项,那么除非你检索时特意额外地使用了 order_by() ,
否则,当你使用 Django 的数据库 API 去检索时, Publisher 对象的相关返回值默认地都会按 name 字段排序
1 class Publisher(models.Model): 2 name = models.CharField(max_length=30) 3 address = models.CharField(max_length=50) 4 city = models.CharField(max_length=60) 5 state_province = models.CharField(max_length=30) 6 country = models.CharField(max_length=50) 7 website = models.URLField() 8 def __unicode__(self): 9 return self.name 10 class Meta: 11 ordering = ['name']
不支持Python的负索引(negative slicing):
1 >>> Publisher.objects.order_by('name')[‐1] 2 Traceback (most recent call last): 3 ... 4 AssertionError: Negative indexing is not supported.
然不支持负索引,但是我们可以使用其他的方法。 比如,稍微修改 order_by() 语句来实现:
1 >>> Publisher.objects.order_by('‐name')[0]
update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录。 以下示例演示如何
将所有Publisher的country字段值由’U.S.A’更改为’USA’:
1 >>> Publisher.objects.all().update(country='USA')
执行原生sql:
执行原始SQL查询
有时候你会发现Django数据库API带给你的也只有这么多,那你可以为你的数据库写一些自定义SQL查询。 你
可以通过导入 django.db.connection 对像来轻松实现,它代表当前数据库连接。 要使用它,需要通
过 connection.cursor() 得到一个游标对像。 然后,使用 cursor.execute(sql, [params]) 来执行SQL语句,使
用 cursor.fetchone() 或者 cursor.fetchall() 来返回记录集。 例如:
1 >>> from django.db import connection 2 >>> cursor = connection.cursor() 3 >>> cursor.execute(""" 4 ... SELECT DISTINCT first_name 5 ... FROM people_person 6 ... WHERE last_name = %s""", ['Lennon']) 7 >>> row = cursor.fetchone() 8 >>> print row 9 ['John']
connection 和 cursor 几乎实现了标准Python DB-API,你可以访问` http://www.python.org/peps/pep-
0249.html <http://www.python.org/peps/pep-0249.html>`__来获取更多信息。 如果你对Python DB-API
不熟悉,请注意在 cursor.execute() 的SQL语句中使用`` “%s”`` ,而不要在SQL内直接添加参数。 如果你使
用这项技术,数据库基础库将会自动添加引号,同时在必要的情况下转意你的参数

浙公网安备 33010602011771号