Gowhich

Durban's Blog

{% for %} 允许我们在一个序列上迭代。与Python的for 语句的情形类似,循环语法是 for X in Y ,Y是要迭代的序列
而X是在每一个特定的循环中使用的变量名称。每一次循环中,模板系统会渲染在{% for %} and {% endfor %} 中的所有内
容。
例如,给定一个运动员列表athlete_list 变量,我们可以使用下面的代码来显示这个列表:

1
2
3
4
5
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>

给标签增加一个reversed 使得该列表被反向迭代:

1
2
3
{% for athlete in athlete_list reversed %}
...
{% endfor %}

可以嵌套使用 {% for %} 标签:

1
2
3
4
5
6
7
8
9
{% for country in countries %}
<h1>{{ country.name }}</h1>
<ul>

{% for city in country.city_list %}
<li>{{ city }}</li>
{% endfor %}
</ul>
{% endfor %}

Django不支持退出循环操作。如果我们想退出循环,可以改变正在迭代的变量,让其仅仅包含需要迭代的项目。同
理,Django也不支持continue语句,我们无法让当前迭代操作跳回到循环头部。
{% for %} 标签在循环中设置了一个特殊的 forloop 模板变量。这个变量能提供一些当前循环进展的信息:
forloop.counter 总是一个表示当前循环的执行次数的整数计数器。这个计数器是从1开始的,
所以在第一次循环时forloop.counter 将会被设置为1。例子如下:

1
2
3
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}

forloop.counter0 类似于 forloop.counter ,但是它是从0计数的。第一次执行循环时这个变量会被设置为0。
forloop.revcounter 是表示循环中剩余项的整型变量。在循环初次执行时 forloop.revcounter 将被设置为序列中项的总
数。最后一次循环执行中,这个变量将被置1。
forloop.revcounter0 类似于 forloop.revcounter ,但它以0做为结束索引。在第一次执行循环时,该变量会被置为序
列的项的个数减1。在最后一次迭代时,该变量为0。
forloop.first 是一个布尔值。在第一次执行循环时该变量为True,在下面的情形中这个变量是很有用的。

1
2
3
4
5
{% for object in objects %}
{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %}

forloop.last 是一个布尔值;在最后一次执行循环时被置为True。一个常见的用法是在一系列的链接之间放置管道符(|)

1
{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}

The above template code might output something like this::
Link1 | Link2 | Link3 | Link4

forloop.parentloop 是一个指向当前循环的上一级循环的 forloop 对象的引用(在嵌套循环的情况下)。例子在此:

1
2
3
4
5
6
7
8
9
10
11
{% for country in countries %}
<table>
{% for city in country.city_list %}
<tr>
<td>Country #{{ forloop.parentloop.counter }}</td>
<td>City #{{ forloop.counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}

forloop 变量仅仅能够在循环中使用,在模板解析器碰到 {% endfor %} 标签时, forloop 就不可访问了。
Context和forloop变量
在一个{% for %} 块中,已存在的变量会被移除,以避免 forloop 变量被覆盖。Django会把这个变量移动到
forloop.parentloop 中。通常我们不用担心这个问题,但是一旦我们在模板中定义了 forloop 这个变量(当然我们反对这
样做),在{% for %} 块中它会在 forloop.parentloop 被重新命名。

如何给 Django 开发的网站添加 favicon.ico 功能

三步:

  1. 创建一个 favicon.ico 文件
  2. 修改 urls.py , 添加 “/favicon.ico” 路径。
  3. 修改 html 模版

下面看实现步骤

第一步:创建一个 favicon.ico 文件

创建了一个 16x16 像素的透明画布,在添加一个text图层(写上“Y”),保存为 png 格式文件 favicon.png , 重命名为 favicon.ico 即可: “ “
第二步:修改 urls.py
在 URL 里添加:

1
(r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': settings.MEDIA_URL+'images/favicon.ico'}),

第三步:修改 html 模版

在 html 模版的 head 部分添加:

1
<link REL="SHORTCUT ICON" HREF="{{ MEDIA_URL }}images/favicon.ico">

语法规则: location [=||*|^~] /uri/ { … }

= 开头表示精确匹配

^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。

~ 开头表示区分大小写的正则匹配

~\* 开头表示不区分大小写的正则匹配

!~!~\*分别为区分大小写不匹配及不区分大小写不匹配 的正则

/ 通用匹配,任何请求都会匹配到。

多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考):

首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

例子,有如下匹配规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
location = / {
#规则A
}
location = /login {
#规则B
}
location ^~ /static/ {
#规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
#规则D
}
location ~* \.png$ {
#规则E
}
location !~ \.xhtml$ {
#规则F
}
location !~* \.xhtml$ {
#规则G
}
location / {
#规则H
}

那么产生的效果如下:

访问根目录/, 比如http://localhost/ 将匹配规则A

访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H

访问 http://localhost/static/a.html 将匹配规则C

访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用, 而 http://localhost/static/c.png 则优先匹配到 规则C

访问 http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。

访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML 不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。

访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。

实际应用中常用的几个规则,如下:

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。 这里是直接转发给后端应用服务器了,也可以是一个静态首页 第一个必选规则

1
2
3
location = / {
proxy_pass http://tomcat:8080/index
}

第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用

1
2
3
4
5
6
7
8
location ^~ /static/ {
# 请求/static/a.txt 将被映射到实际目录文件: /webroot/res/static/a.txt
root /webroot/res/;
}

location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}

第三个规则就是通用规则,用来转发动态请求到后端应用服务器 非静态文件请求就默认是动态请求,自己根据实际把握 毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了

1
2
3
location / {
proxy_pass http://tomcat:8080/
}

对于以上基础推荐配置,有一个补充,就是关于转发有一点需要注意。例如下面配置,对一个目录转发:

关键在于最后的/,访问localhost/outer/in.html,其中case A 会转发到tomcat:8080/in.html, 而case B 会转发到 tomcat:8080/outer/in.html,所以务必注意了。

未试验过的其他信息:

三、ReWrite语法
last – 基本上都用这个Flag。
break – 中止Rewirte,不在继续匹配
redirect – 返回临时重定向的HTTP状态302
permanent – 返回永久重定向的HTTP状态301
1、下面是可以用来判断的表达式:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
2、下面是可以用作判断的全局变量
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:\nginx/html
$request_filename:D:\nginx/html/test1/test2/test.php
四、Redirect语法

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name www.gowhich.com;
index index.html index.php;
root html;
if ($http_host !~ "^www\.gowhich\.com$" {
rewrite ^(.*) http://gowhich.com$1 redirect;
}
}

五、防盗链

1
2
3
4
5
6
location ~* \.(gif|jpg|swf)$ {
valid_referers none blocked gowhich.com www.gowhich.com;
if ($invalid_referer) {
rewrite ^/ http://$host/logo.png;
}
}

六、根据文件类型设置过期时间

1
2
3
4
5
6
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
expires 1h;
break;
}
}

七、禁止访问某个目录

1
2
3
4
location ~* \.(txt|doc)${
root /data/www/wwwroot/test;
deny all;
}

八、直接访问某个指定文件

1
2
3
4
location = ads.txt {
# /data/www/wwwroot/目录下要有ads.txt文件
root /data/www/wwwroot/;
}

一些可用的全局变量
$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri

第一步:介绍我的文件目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
walkerfree  
----walkerfree
--------__init__.py
--------settings.py
--------urls.py
--------wsgi.py
----blog
--------__init__.py
--------models.py
--------views.py
--------test.py
----static
--------css
------------style.css
--------js
------------jquery.js
--------images
------------me.jpg
----media
--------upload
----manage.py

第二步:settings文件的配置的简介

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# -*- coding: utf-8 -*-
# Django settings for walkerfree project.

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
('漫步者Feeling', 'xx@xx'),
)

MANAGERS = ADMINS

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'walkerfree', # Or path to database file if using sqlite3.
'USER': 'root', # Not used with sqlite3.
'PASSWORD': 'zhangda890126;;', # Not used with sqlite3.
'HOST': 'localhost', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '3306', # Set to empty string for default. Not used with sqlite3.
}
}

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'Asia/Chongqing'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = '/home/davidzhang/walkerfree/media'

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = '/media/'

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT ='/home/davidzhang/walkerfree/static/'

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'

# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = '0h&amp;*b8sw)*fu_oy+jj_%bun3*&amp;3v&amp;*!5#79un!do71eq4su86x'

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)

MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'walkerfree.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'walkerfree.wsgi.application'

TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
"/home/davidzhang/walkerfree/templates"
)

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'walkerfree',
)

# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}

第三步:nginx的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 80; ## listen for ipv4; this line is default and implied
root /home/davidzhang/walkerfree/walkerfree;
index index.html index.htm;

# Make site accessible from http://localhost/
server_name local.ubuntu.walkerfree.com;

access_log /var/log/uwsgi/local.ubuntu.walkerfree.access.log;
error_log /var/log/uwsgi/local.ubuntu.walkerfree.error.log;

location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/mysite.socket;
}

#here is important
location ^~ /static/ {
root /home/davidzhang/walkerfree/;
}
}

ok,搞定了

想要我uwsgi配置的,请期待下篇文章

在使用django的时候,会遇到一个问题,就是“Non-ASCII character ‘\xe6’”这个错误

原因是如下,是我的配置文件中的一部分代码

1
2
3
4
5
6
DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
('漫步者Feeling', 'xx@xx'),
)

提示一下,这里有中文,就是这个原因

修改一下,如下:

1
2
3
4
5
6
7
8
9
# -*- coding: utf-8 -*-
# Django settings for walkerfree project.

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
('漫步者Feeling', 'xx@xx'),
)

就是这句代码:# -*- coding: utf-8 -*-

解决了。

想要去掉字符串的前后空格和回车符,很简单,如下:

1
2
3
4
NSString *string = @" spaces in front and at the end ";
NSString *trimmedString = [string stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(trimmedString);

今天搞了一下禁止nginx的ip访问,哈哈,找了一篇文章

看下面‍

在虚拟主机最前面加上如下即可,记住一定要以它开头(不然不生效)。如下,返回值404,可以改403等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server {
server_name _; #default
return 404;
}


server{
listen 80;
server_name .test.com; #(域名前加点,不然可能访问不了)
index main.php index.php;
root /var/htdocs/www/test;

location ~ .*\.(php|php5)?${
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

log_format testlogs '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
access_log /var/htdocs/logs/testlogs.log testlogs;

}

关于根据条件选择Storyboard,我之前的一篇文章,今天使用的时候,不起作用了,悲剧,今天又自己写了一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//主要的storyboard - xunYi7TabBarViewController
//login的storyboard - login

UIViewController *rootViewController;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
if([[NSUserDefaults standardUserDefaults] boolForKey:@"logged_in"]) {

rootViewController = [[UIStoryboard
storyboardWithName:@"MainStoryboard" bundle:nil]
instantiateViewControllerWithIdentifier:@"xunYi7TabBarViewController"];
}else{

rootViewController = [[UIStoryboard
storyboardWithName:@"LoginStoryboard" bundle:nil]
instantiateViewControllerWithIdentifier:@"login"];
}
self.window.rootViewController=rootViewController;

[self.window makeKeyAndVisible];
return yes;

如果这个例子不起作用,也可以尝试我之前的那篇文章iOS启动 判断使用不同的 storyboard

如果访问量大,可能产生的 SESSION 文件会比较多,这时可以设置分级目录进行 SESSION 文件的保存,效率会提高很多,设置方法为:session.save_path=”N;/save_path”,N 为分级的级数,save_path 为开始目录。当写入 SESSION 数据的时候,PHP 会获取到客户端的 SESSION_ID,然后根据这个 SESSION ID 到指定的 SESSION 文件保存目录中找到相应的 SESSION 文件,不存在则创建之,最后将数据序列化之后写入文件。 检查了下各web节点,所有web服务器的httpd线程均达到满负荷,很奇怪。因为所有web节点都通过nfs来共享session目录来达到 session的一致性,检查了下nfs文件服务器,IO读写比较大,检查了session_tmp目录,发现session目录临时文件达到 70000多个,初步判断也许是因为一级目录下文件过多带来的IO性能下降。

以前没有想过session存放的效率问题,今天由此想到了session多级存放的问题,来解决一个目录下session文件过多带来的读写效率问题,查了下php.net其实php在配置中已经给出了有关选项。

php.net上的:http://www.php.net/manual/en/ref.session.php

session.save_path 定义了传递给存储处理器的参数。如果选择了默认的 files 文件处理器,则此值是创建文件的路径。默认为 /tmp。参见 session_save_path()。 此指令还有一个可选的 N 参数来决定会话文件分布的目录深度。例如,设定为 ‘5;/tmp’ 将使创建的会话文件和路径类似于
/tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If。 要使用 N 参数,必须在使用前先创建好这些目录。在 ext/session 目录下有个小的 shell 脚本名叫 mod_files.sh 可以用来做这件事。此外注意如果使用了 N 参数并且 N 大于 0,那么将不会执行自动垃圾回收,更多信息见 php.ini。另外如果用了 N 参数,要确保将 session.save_path 的值用双引号 “quotes” 括起来,因为分隔符分号( ;)在 php.ini 中也是注释符号。
session.save_path string
在定义session.save_path中可以定义多级存放的路径,修改php.ini
session.save_path = "3;/tmp/session"
将session文件分成两级存放,即/tmp/session/c/m/d/0/o/sess_cmd0on71pr8kf1dogkesn59s30,取前两位字符,但是php并不生成目录,需要自己手工生成,所以写了个脚本来生成初始的目录。
附上一个创建四级文件夹包的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/local/php/bin/php
<?php
$string = '0123456789abcdefghijklmnopqrstuvwxyz';
$length = strlen($string);
for($i=0;$i<$length;$i++){
for($j=0;$j<$length;$j++){
for($k=0;$k<$length;$k++){
for($m=0;$m<$length;$m++){
echo $path = '/tmp/session/'.$string[$i].'/'.$string[$j].'/'.$string[$k].'/'.$string[$m];
createFolder($path);
echo "\n";
}
}
}
}

function createFolder($path){
if(!file_exists($path)){
createFolder(dirname($path));
mkdir($path,0777);
}
}
exit;
?>
0%