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内直接添加参数。 如果你使
用这项技术,数据库基础库将会自动添加引号,同时在必要的情况下转意你的参数

 

posted @ 2016-10-03 18:37  evil_liu  阅读(145)  评论(0)    收藏  举报