django入门(三)Session、wiki示例
阅读别人的中文笔记
http://www.woodpecker.org.cn/obp/django/django-stepbystep/newtest/doc/
step by step(五)
1.新建Login.py文件:
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
def login(request):
username = request.POST.get("username",None)
if username:
request.session["username"] = username
username = request.session.get("username",None)
if username:
return render_to_response("login.html",{"username":username})
else:
return render_to_response("login.html")
def logout(request):
try:
del request.session["username"]
except KeyError:
pass
return HttpResponseRedirect("/login/")
导入了session模块,从session中存取变量
2.新建模版文件/template/login.html
{% if not username %}
<form method="post" action="/login/">
用户名:<input type="text" name="username" value=""><br/>
<input type="submit" value="登录">
</form>
{% else %}
你已经登录了!{{ username }}<br/>
<form method="post" action="/logout/">
<input type="submit" value="注销">
</form>
{% endif %}
3.修改了最重要的urls.py文件,加入如下内容:
(r'^login/$', 'easydjango.src.com.sillycat.easydjango.Login.login'),
(r'^logout/$', 'easydjango.src.com.sillycat.easydjango.Login.logout'),
4.也是到了这里才知道,django的session是存在数据库中的,所以这里要在settings.py中打开数据库的配置,这里学习为了先简单玩,所以用内置的sqlite3
DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = './data.db' # Or path to database file if using sqlite3.
DATABASE_USER = '' # Not used with sqlite3.
DATABASE_PASSWORD = '' # Not used with sqlite3.
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
5.同时还需要初始化数据库
D:\work\easydjango>manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
You just installed Django's auth system, which means you don't have any superuse
rs defined.
Would you like to create one now? (yes/no): no
Installing index for auth.Permission model
Installing index for auth.Message model
初始化完成后,会在目录上生成一个数据库文件data.db,访问http://localhost:8000/login就可以看到效果了。
step by step(六)
1.创建app模块
manage.py startapp wiki
这样就在目录easydjango项目下新建了子目录wiki并生成了如下四个文件
__init__.py 表示是一个py目录
models.py 存放所有的model对象
tests.py 暂时没有使用
views.py 相当于我们的controller层
2.编辑wiki/models.py建立Wiki对象
from django.db import models
class Wiki(models.Model):
#pagename = models.CharField(maxlength=20, unique=True)
pagename = models.CharField(max_length=20, unique=True)
content = models.TextField()
建立了Wiki对象,包含两个元素,其中的pagename是唯一标示符,content是内容。
3.修改settings.py,安装这个app
在最后增加了一行,修改结果如下:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'easydjango.wiki'
)
然后,根据model生成数据库的表,执行命令如下:
manage.py syncdb
报错如下:
TypeError: __init__() got an unexpected keyword argument 'maxlength'
看来是版本问题,参考文档:
http://docs.djangoproject.com/en/dev/ref/models/fields/
修改为
pagename = models.CharField(max_length=20, unique=True) 就OK了。
D:\work\easydjango>manage.py syncdb
Creating table wiki_wiki
4.在命令行下加入首页
#调用shell命令
D:\work\easydjango>manage.py shell
Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from easydjango.wiki.models import Wiki
>>> page = Wiki(pagename='index',content='Welcome to Wiki')
>>> page.save()
#其实执行到这里已经保存成功了,下面的all(),all()[0]等,都是在查看元素了
>>> Wiki.objects.all()
[<Wiki: Wiki object>]
>>> p = Wiki.objects.all()[0]
>>> p.pagename
u'index'
>>> p.content
u'Welcome to Wiki'
5.修改wiki/views.py改写controller层代码
#coding=utf-8
from easydjango.wiki.models import Wiki
from django.template import loader, Context
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
#正则表达式
import re
def index(request, pagename=""):
"""显示正常页面,对页面的文字做特殊的链接处理"""
if pagename:
#查找是否已经存在页面
pages = Wiki.objects.filter(pagename=pagename)
if pages:
#存在则调用页面模板进行显示
return process('wiki/page.html', pages[0])
else:
#不存在则进入编辑画面
return render_to_response('wiki/edit.html', {'pagename':pagename})
else:
page = Wiki.objects.get(pagename='FrontPage')
return process('wiki/page.html', page)
def edit(request, pagename):
"""显示编辑存在页面"""
page = Wiki.objects.get(pagename=pagename)
return render_to_response('wiki/edit.html', {'pagename':pagename, 'content':page.content})
def save(request, pagename):
"""保存页面内容,老页面进行内容替换,新页面生成新记录"""
content = request.POST['content']
pages = Wiki.objects.filter(pagename=pagename)
if pages:
pages[0].content = content
pages[0].save()
else:
page = Wiki(pagename=pagename, content=content)
page.save()
return HttpResponseRedirect("/wiki/%s" % pagename)
r = re.compile(r'\b(([A-Z]+[a-z]+){2,})\b')
def process(template, page):
"""处理页面链接,并且将回车符转为<br>"""
t = loader.get_template(template)
content = r.sub(r'<a href="/wiki/\1">\1</a>', page.content)
content = re.sub(r'[\n\r]+', '<br>', content)
print content
#c = Context({'pagename':page.pagename, 'content':content})
c = Context({'pagename':page.pagename, 'content':content},autoescape=False)
#发现render的过程自动转义了html,所以没有达到demo上需要的效果
v_str = t.render(c)
print v_str
return HttpResponse(v_str)
其中在process方法中,要实现step by step中的效果,要加上autoescape=False,可能因为我使用的django版本1.1.1和文章中有差异
6.在template中创建wiki目录
编辑template/wiki/page.html
<h2>{{ pagename }}</h2>
<p>{{ content }}</p>
<hr />
<p>
<form method="POST" action="/wiki/{{pagename}}/edit/"><input
type="submit" value="编辑"></form>
</p>
编辑template/wiki/edit.html
<h2>编辑:{{ pagename }}</h2>
<form method="POST" action="/wiki/{{pagename}}/save/"><textarea
name="content" rows="10" cols="50">{{ content }}</textarea><br />
<input type="submit" value="保存"></form>
7.修改urls.py文件建立views.py里面方法和url的关系
(r'^wiki/$', 'easydjango.wiki.views.index'),
(r'^wiki/(?P<pagename>\w+)/$', 'easydjango.wiki.views.index'),
(r'^wiki/(?P<pagename>\w+)/edit/$', 'easydjango.wiki.views.edit'),
(r'^wiki/(?P<pagename>\w+)/save/$', 'easydjango.wiki.views.save'),
这里的正则表达式会讲参数pagename传递到方法中,wiki/pagename 就是显示一个页面,wiki/pagename/edit 就是编辑这个页面, wiki/pagename/save 就是保存页面。而 pagename 解析出来后就是分别与 index() , edit() , save() 的 pagename 参数相对应。
8启动server
manage.py runserver后访问,http://localhost:8000/wiki
编辑第一个页面加上wiki的第二个链接
Welcome to Wiki
FirstPage
再点击FirstPage在里面加上如下内容:
first page content view!
back to FrontPage
这样wiki两个页面都OK了,一个FrontPage首页,下面的FirstPage,SecondPage...就自己慢慢玩了。