24.优化模板 html
在这个项目中,从已经作过的模板来看,你可能会注意到里面有不少重复的代码。这种重复不只带来大量无谓的工做量,并且之后调整起来也极为不便。python
所以,最理想的作法是将那些重复的代码放到基础模板中,而后从基础模板再扩展出一个个新的模板。chrome
咱们先来作这个基础模板,在templates文件夹下新建一个base.html文件,而后添加如下内容:django
templates/base.html:浏览器
<!DOCTYPE html> <html> <head> <title>Rango - {% block title %}实战Django!{% endblock %}</title> </head> <body> <div> {% block body_block %}{% endblock %} </div> <hr /> <div> <ul> {% if user.is_authenticated %} <li><a href="/rango/restricted/">限制页面</a></li> <li><a href="/rango/logout/">注销</a></li> <li><a href="/rango/add_category/">新建分类</a></li> {% else %} <li><a href="/rango/register/">注册</a></li> <li><a href="/rango/login/">登陆</a></li> {% endif %} <li><a href="/rango/about/">关于</a></li> </ul> </div> </body> </html>
咱们来修改一下category.html这个模板,把内容改为下面这样:安全
templates/rango/category.html:服务器
{% extends 'base.html' %} {% load staticfiles %} {% block title %}` category_name `{% endblock %} {% block body_block %} <h1>` category_name `</h1> {% if category %} {% if pages %} <ul> {% for page in pages %} <li><a href="` page`.`url `">` page`.`title `</a></li> {% endfor %} </ul> {% else %} <strong>当前分类下尚无可用页面!</strong> {% endif %} {% if user.is_authenticated %} <a href="/rango/category/`category`.`slug`/add_page/">添加页面</a> {% endif %} {% else %} 指定的分类名称 ` category_name ` 不存在! {% endif %} {% endblock %}
注意,咱们在第一行中写了一句”{% extends 'rango/base.html' %} “,它表示本模板继承了base.html这个模板,这样咱们在这个模板中就只需专一添加”block title“和”body_block “这两块就行!cookie
咱们能够用一样的方式对其它的模板进行处理。网络
在基础模板中,咱们还能够直接引用url的名称。好比“关于”页面的连接,原来写的是:“session
templates/rango/base.html:
<li><a href="{% url 'about' %}">关于</a></li>
当程序看到“{% url …}”的时候,它会自动去urls.py文件中找相应的名称(好比说”about”).这样写的好处是,之后当咱们要修改连接时,没必要去逐个改动模板,而只要在urls.py中进行修改就能够了!
”关于“这个页面的连接咱们还能够这样写:
<li><a href="{% url 'rango.views.about' %}">关于</a></li>
这至关于告诉程序,到”rango”这个应用中,找一个叫”about”的视图。不过我仍是更喜欢前面一种写法。
咱们能够将base.html模板中的那些连接写成这样:
templates/rango/base.html(更新</body>前面的最后一个<div>标签里的内容):
<div> <ul> {% if user.is_authenticated %} <li><a href="{% url 'restricted' %}">限制页面</a></li> <li><a href="{% url 'logout' %}">注销</a></li> <li><a href="{% url 'add_category' %}">新建分类</a></li> {% else %} <li><a href="{% url 'register' %}">注册</a></li> <li><a href="{% url 'login' %}">登陆</a></li> {% endif %} <li><a href="{% url 'about' %}">关于</a></li> </ul> </div>
咱们再来看看首页模板,在index.html中,咱们能够用一样的方式来改造。
好比category的连接,咱们能够写成:
templates/rango/index.html(找不到么?用第一行代码搜索一下!):
{% for category in categories %} <!-- 下面这行给分类加入了超连接 --> <li><a href="{% url 'category' category.slug %}">` category`.`name `</a></li> {% endfor %}
你能够尝试将全部的连接都改写过来,舍得建议你们一开始就养成这样写的习惯。
25.Cookies(信息指纹)和Sessions(会话)
Cookies和Sessions在当今的网络应用程序中是极为重要的。事实上在以前咱们讲到登陆和注销的模块时,咱们已经用到了Cookies和Sessions,只不过没告诉你罢了。如今咱们来看看Cookies和Sessions在其它方面的应用。
先来段测试。找到rango/views.py,在index视图的第一行插入以下代码:
rango/views.py:
request.session.set_test_cookie()
而后找到register视图,在第一行插入下面三行代码:
if request.session.test_cookie_worked(): print (">>>> TEST COOKIE WORKED!") request.session.delete_test_cookie()
加完上面这些代码(注意缩进哦),在浏览器的地址栏中输入:
http://127.0.0.1:8000/rango/
而后点击”注册“连接,你应该能够在你的Django服务器控制台(Dos命令提示符下,还记得执行”python manage.py runserver”的地方不?)下看到以下的字样:
>>>> TEST COOKIE WORKED!
若是看不到,多是你的浏览器中禁用了Cookies。
好了,刚才只是一个测试,如今你能够删掉添加那几行代码,继续往下看。
咱们知道cookies已经能正常工做了,让咱们来作一个很是简单的站点访问数统计。要实现这项功能,咱们须要作两个cookies,一个用来记录用户访问Rango的次数,另外一个则用来记录用户上一次访问Rango的时间,第二个cookies能够帮助咱们统计那些一天内频繁访问Rango的用户,无论他一天访问多少次,咱们只算他一次的访问量。
编辑rango/views.py,修改index视图:
rango/views.py:
def index(request): category_list = Category.objects.all() page_list = Page.objects.order_by('-views')[:5] context_dict = {'categories': category_list, 'pages': page_list} # 获取站点的访问量 # 咱们用COOKIES.get()方法来获取cookie中的访问数据 # 若是cookie存在,则把返回的数值转成整数 # 若是cookie不存在,则将visits值设定为0 visits = int(request.COOKIES.get('visits', '0')) reset_last_visit_time = False # cookie中有last_visit这个值吗? if 'last_visit' in request.COOKIES: # 好滴,果真有这个值 last_visit = request.COOKIES['last_visit'] # 将这个值用python的datetime库转换为特定的日期格式 last_visit_time = datetime.strptime(last_visit[:-7], "%Y-%m-%d %H:%M:%S") # 若是从上次登陆到如今已经超过一天,则访问数加1... if (datetime.now() - last_visit_time).days > 0: visits = visits + 1 # ...将重置last_visit时间的信号设为True,表示此值须要更新 reset_last_visit_time = True else: # Cookie中没有last_visit值, 也将重置last_visit时间的信号设为True reset_last_visit_time = True context_dict['visits'] = visits # 先渲染出response对象,以便增长cookie信息 response = render(request, 'rango/index.html', context_dict) if reset_last_visit_time: response.set_cookie('last_visit', datetime.now()) response.set_cookie('visits', visits) # 将response对象返回给用户,更新需更改的cookie值 return response
由于咱们这里用到了Python的datetime库,别忘了在文件头部加入这样一句:
from datetime import datetime
咱们来看一下效果,在谷歌浏览器(chrome)中输入:http://127.0.0.1:8000/rango/,首页出现了。
若是想看到访问数据,须要作如下几步操做:
若是visits数据为0,不妨修改一下系统时间(改到明天便可),而后再刷新浏览器的页面,你就能够观察到数据的变化了。
上面这个例子的访问数据是储存在用户的电脑上的,然而,更安全也更经常使用的作法是将会话信息储存到服务器上。
要使用基于cookie的会话,你须要检查一下Rango的环境:
若是你在前面一步步作下来,那么这两项都应该符合要求的。
咱们再来编辑rango/views.py,修改index视图:
rango/views.py:
def index(request): category_list = Category.objects.order_by('-likes')[:5] page_list = Page.objects.order_by('-views')[:5] context_dict = {'categories': category_list, 'pages': page_list} visits = request.session.get('visits') if not visits: visits = 0 reset_last_visit_time = False last_visit = request.session.get('last_visit') if last_visit: last_visit_time = datetime.strptime(last_visit[:-7], "%Y-%m-%d %H:%M:%S") if (datetime.now() - last_visit_time).seconds > 0: # ...访问数加1... visits = visits + 1 # ...发出更新last_visit值的信号 reset_last_visit_time = True else: # last_visit值不存在,发出建立last_visit值的信号. reset_last_visit_time = True context_dict['visits'] = visits request.session['visits'] = visits if reset_last_visit_time: request.session['last_visit'] = str(datetime.now()) response = render(request,'rango/index.html', context_dict) return response
【未完待续】