1、win7下,无法使用 django-admin.py startproject mysite建立工程。
这是django的一个bug,网上说可以通过修改注册表解决,但尝试后不行。最后可使用python c:django-1.5.8/django/bin/django-admin.py startproject mysite成功建立了工程。
2、修改环境变量后无法直接使用django-admin.py。
修改环境变量后,需要重启电脑才能生效。
3、视图与URL配置相关(一般内容参见第三章内容)
(1)在views.py中新建一个视图。视图其实就是一个py函数,一个函数对应一个request,返回一个response。
(2)注意:views.py是建立在第二层项目文件夹中,跟url.py在同一层,而不是跟manage.py在同一层。
(3)在urls.py中添加映射
from django.conf.urls.defaults import * from mysite.views import hello urlpatterns = patterns('', ('^hello/$', hello), )
文件夹中的views.py对应成工程mysite的一个模块,函数hello()从对应的模块导入
(4)映射通过正则表达式匹配,一般需要匹配开头与结尾。
(5)最后,凡是本站域名128.0.0.1:8000/hello/的都映射到hello函数进行response。(正则表达式规定了url以hello/开头和结尾)
4、django模板相关
(1)模板中{{ }}代表变量;
{% %}为模板标签,用于通知模板完成某种工作;有if标签、for标签等,用法与C语言的差不多;
(2)使用模板出错:无法使用t = template.Template('My name is {{ name }}.')
解决:先导入from django.conf import settings,再运行settings.configure()
原因:
转到project目录(在第二章由 django-admin.py startproject 命令创建), 输入命令 python manage.py shell启动交互界面。
(3)定义一个context,用于与模板的标签映射
>>> t = template.Template('My name is {{ name }}.') >>> c = template.Context({'name': 'Adrian'}) >>> print t.render(c) My name is Adrian.
可以在template里面直接调用类的属性,然后在context中映射类对象即可(使用字典的键与值也一样),如
>>> d = datetime.date(1993, 5, 2) >>> d.year 1993 >>> d.month 5 >>> d.day 2 >>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.') >>> c = Context({'date': d}) >>> t.render(c) u'The month is 5 and the year is 1993.'
也可以调用该类的方法,但注意,只能调用没有参数的方法,调用时使用.method的形式,不用添加括号。
使用列表作为tab也可以,使用list.2的方式调用,表示调用列表第二个项
5、标签相关
(1)标签中的if语句,else可选,并可以使用逻辑判断(PS:同一标签不能同时出现and 和 or)
{% if today_is_weekend and today_is_sunday %} <p>Welcome to the weekend!</p> {% else %} <p>Get back to work.</p> {% endif %}
(2)for标签
{% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %}
in后必须是可迭代对象。可在最后加上reversed反向遍历;for可以嵌套;
for还有一个可选的empty分句,可以在对象为空时显示,如下
{% for athlete in athlete_list %} <p>{{ athlete.name }}</p> {% empty %} <p>There are no athletes. Only computer programmers.</p> {% endfor %}
每个for循环中有个forloop.counter(或forcounter0,从0开始计数),从1开始计数,记录循环进行到第几次;还有一个forloop.revcounter,开始时为序列总数,每次递减;forloop.first是一个布尔值,第一次迭代时为真;forloop.last最后一次迭代时为真。forloop.paraentloop是嵌套的上个for的forloop的引用。
{% for item in todo_list %} <p>{{ forloop.counter }}: {{ item }}</p> {% endfor %}
(3)比较是否相等
{% ifequal user currentuser %} <h1>Welcome!</h1> {% endifequal %}
也可以添加else分句;
6、多行注释
{% comment %} This is a multi-line comment. {% endcomment %}
7、过滤器
过滤器使用管道符号|来连接,被处理的对象放在最前,后面可以一次添加管道;有的管道会包含参数,参数使用双引号“”包围;
8、模板使用
为了把网页设计模板与python代码分离,可在项目文件夹下新建templates文件夹,并使用get_template来加载模板,必须在settings.py中添加TEMPLATE_DIRS指定模板目录
TEMPLATE_DIRS=( 'E:/djangodev/mysite/mysite/templates', )
模板的使用如下
from django.template.loader import get_template from django.template import Context def current_datetime(request): now = datetime.datetime.now() t = get_template('current_datetime.html') html = t.render(Context({'current_date': now})) return HttpResponse(html)
更方便的返回一个渲染模板:render_to_response()
from django.shortcuts import render_to_response import datetime def current_datetime(request): now = datetime.datetime.now() return render_to_response('current_datetime.html', {'current_date': now})
如果在指定的templates下有子文件夹,则在gettemplates和rendertoresponse时添加相对路径即可,如
t = get_template('apptemplates/current_datetime.html')
在模板中添加其他模板的内容(一般是一些常用的模板),可以使用include
<html> <body> {% include "includes/nav.html" %} <h1>{{ title }}</h1> </body> </html>
9、模板重载
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="en"> <head> <title>{% block title %}{% endblock %}</title> </head> <body> <h1>My helpful timestamp site</h1> {% block content %}{% endblock %} {% block footer %} <hr> <p>Thanks for visiting my site.</p> {% endblock %} </body> </html>
使用block标签来代表子模板可以重载的部分,每个block可以起一个名字
使用extend来继承父模板,子模板只是写出与父模板不同之处即可
{% extends "base.html" %} {% block title %}The current time{% endblock %} {% block content %} <p>It is now {{ current_date }}.</p> {% endblock %}
你可以根据需要使用任意多的继承次数。 使用继承的一种常见方式是下面的三层法:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'iyjhabc', 'PASSWORD': '', 'HOST': '', 'PORT': '', } }
(3)在mysite下创建一个app
python manage.py startapp books
(4)在app的models.py下使用函数的形式填写表信息
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField()
(5)修改setting.py激活APP
INSTALLED_APPS = ( # 'django.contrib.auth', # 'django.contrib.contenttypes', # 'django.contrib.sessions', # 'django.contrib.sites', 'books',//书上此处错误 )
(6)检验模型有效性
python manage.py validate
(7)生成SQL语句。PS:此时并未在数据库使用这些SQL语句
python manage.py sqlall books
(8)把models.py的内容同步到数据库。PS:如果models.py中的表尚未新建,则同步会新建这些表,如果对表进行了修改,则同步不会修改这些表。
python manage.py syncdb
(9)使用之前已经定义好的 Model的子类Pubilisher来把数据添加到数据库
>>> from books.models import Publisher >>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue', ... city='Berkeley', state_province='CA', country='U.S.A.', ... website='http://www.apress.com/') >>> p1.save()
注意,只有使用save()的时候才正式将数据写入数据库。
(10)直接使用create()函数就可以一次进行填写数据和写数据库的功能
>>> p1 = Publisher.objects.create(name='Apress', ... address='2855 Telegraph Avenue', ... city='Berkeley', state_province='CA', country='U.S.A.', ... website='http://www.apress.com/')
11、数据库查询等操作
可以使用fliter()进行SQL的where操作
>>> Publisher.objects.filter(name='Apress')
也可以传递多个参数给fliter,相当于使用SQL的and
Publisher.objects.filter(country="U.S.A.", state_province="CA")
使用contains进行模糊查询,XX 两个下划线 contains,相当于like
Publisher.objects.filter(name__contains="press")
fliter是获取一个结果集,使用get()获取单个对象,当查询到0个或者多于1个结果是,会抛出异常
Publisher.objects.get(country="U.S.A.")
使用orderby来排序,逆序的话在排序项目前面加“-”
Publisher.objects.order_by("name")
Publisher.objects.order_by("-name")
连锁查询,相当于添加多个条件的SQL语句
Publisher.objects.filter(country="U.S.A.").order_by("-name")
使用python列表分片的形式可以提取结果的部分,如下是提取第一个元素
Publisher.objects.filter(country="U.S.A.")[0]
12、数据库更新
如果要修改一个数据项,则不使用save(),因为他会更新所有数据项,使用update()
>>> Publisher.objects.filter(id=52).update(name='Apress Publishing')
也可以对包含多个纪录的子集进行更新,返回受影响子集个数
>>> Publisher.objects.all().update(country='USA')
2
输出数据,delete()
Publisher.objects.filter(country='USA').delete()
13、创建admin站点管理页面
Activating the Admin Interface
The Django admin site is entirely optional, because only certain types of sites need this functionality. That means you’ll need to take a few steps to activate it in your project.
First, make a few changes to your settings file:
- Add 'django.contrib.admin' to the INSTALLED_APPS setting. (The order of INSTALLED_APPS doesn’t matter, but we like to keep things alphabetical so it’s easy for a human to read.)
- Make sure INSTALLED_APPS contains 'django.contrib.auth', 'django.contrib.contenttypes','django.contrib.messages' and 'django.contrib.sessions'. The Django admin site requires these three packages. (If you’re following along with our ongoing mysite project, note that we commented out these four INSTALLED_APPS entries in Chapter 5. Uncomment them now.)
- Make sure MIDDLEWARE_CLASSES contains 'django.middleware.common.CommonMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.contrib.sessions.middleware.SessionMiddleware' and'django.contrib.auth.middleware.AuthenticationMiddleware'. (Again, if you’re following along, note that we commented them out in Chapter 5, so uncomment them.)
Second, run python manage.py syncdb. This step will install the extra database tables that the admin interface uses. The first time you run syncdb with 'django.contrib.auth' in INSTALLED_APPS, you’ll be asked about creating a superuser. If you don’t do this, you’ll need to run python manage.py createsuperuser separately to create an admin user account; otherwise, you won’t be able to log in to the admin site. (Potential gotcha: thepython manage.py createsuperuser command is only available if 'django.contrib.auth' is in your INSTALLED_APPS.)
Third, add the admin site to your URLconf (in urls.py, remember). By default, the urls.py generated bydjango-admin.py startproject contains commented-out code for the Django admin, and all you have to do is uncomment it. For the record, here are the bits you need to make sure are in there:
# Include these import statements... from django.contrib import admin admin.autodiscover() # And include this URLpattern... urlpatterns = patterns('', # ... (r'^admin/', include(admin.site.urls)), # ... )
把models放入admin页面管理
在该app books下的admin.py下,注册各个模型
from django.contrib import admin # Register your models here. from books.models import Publisher, Author, Book admin.site.register(Publisher) admin.site.register(Author) admin.site.register(Book)
14、表单
使用表单一般就是使用HttpRequest,分为GET和POST两种方法,原理与之前学过的JAVA差不多,GET使用url的形式提交参数,POST使用tcp的方式通过服务器提交。值得关注的是HttpRequest类有很方法用于获取用户的信息,需要慢慢积累。
处理表单的流程: 页面(urls.py)-> python 方法(处理表单数据) -> response(相应出一个结果页面)
使用到的页面一般使用模板,并用读取到的输入数据和查询结果填充模板。
在文件夹中新建contact来存放联系相关的页面,此时必须新建一个__init__.py的文件,否则python无法找到contact下面的类。(也可以用startapp命令来完成)
始终要明白,当通过一系列的数据来创建表单对象,并验证通过的时候,就要使用cleaned_data属性进行‘清理工作’,所谓的清理就是对给定的数据对应到python类型。返回的是一组被清理过的字典类型数据。
>>> boundF.cleaned_data {'age': 22, 'name': u'BeginMan', 'email': u'xinxinyu2011@163.com'}
可以在表单中使用隐藏项,用于记录传递数据:当有数据需要传递给下一页面,可定义隐藏表单项
article_id = forms.CharField(widget=forms.HiddenInput())
然后给这个项赋一个厨师值
edit_form = EditForm(initial={ 'article_id':article_id,})
下个页面就可以用GET读取这个值
15、把菜单封装成tag,并关联响应函数
tage_pages.py
from django import template register = template.Library() @register.inclusion_tag('tags/landing_header.html', takes_context=True) def landing_header(context, nav): return {'nav': nav, 'user': context['request'].user}
把landing_header这个tag与此函数与html文件关联起来
使用landing_header这个tag的html页面.html
{% load tags_pages %} #加载tag所在的py文件 {% recent_app_menu %} #使用tag,后可加空格带参数
一个tag其实就是翻译成一段带模板的html代码,不一定是一个完成的html页面