Part 1 通过举例,从整体上过了一遍django的基本内容,包括project, app, database, model等内容。有几下内容需要注意:
project vs. app
app是一个web应用程序,它是实际用来做事的,比如zinnia这个用django写的博客引擎就是一个app,但是一个project是配置文件和app的集合,相当于一个容器。一个project能够包含多个app,同时,一个app也能被多个project包含。
syncdb
python manage.py syncdb 会为该project内的所有app进行数据库初始化,创建表结构,初始化数据,创建索引等。若有app改变了数据库结构,或者是有新的app增加进来,要创建新的表结构,再次运行syncdb,会为这些app进行数据库变更。django怎么识别哪个app是关联了数据库的?要知道自定义的model都是继承自django.db.models.Model这个类的。
Django Model API
Django提供了非常丰富的对Model进行操作的接口,增删查改,样样俱全,比如get(), all(), save(), filter(), delete(), 还有外键xxx_set等
这部分主要讲的是Django的admin功能,即“django.contrib.admin”这个app的功能。"django.contrib.admin"的强大在于它提供了一个管理员后台,可以对你添加的model进行增删查改,以及进行很多的定制。
要想让你添加的model能被后台看到并管理起来,首先要在app的admin.py模块中对Model进行注册。
from django.contrib import admin
from polls.models import Poll
admin.site.register(Poll)
对model进行自定义:
from django.contrib import admin
from polls.models import Poll
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
('Date information', {'fields': ['pub_date']}),
]
admin.site.register(Poll, PollAdmin)
from django.contrib import admin
from polls.models import Choice, Poll
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
admin.site.register(Poll, PollAdmin)
可以改变ChoiceInline的父类,继承自admin.TabularInline,那么可以改变被关联的model显示的样式
django提供了list_display属性来实现这个功能:
class PollAdmin(admin.ModelAdmin):
# ...
list_display = ('question', 'pub_date', 'was_published_recently')
list_filter 和 search_fields
list_filter会在右侧添加一个filter sidebar,可以快捷的进行过滤,而search_fields可以根据传进去的字段进行搜索,都是比较有用的功能。
template loader
template loader是什么?首先它是一个类,这个类规定了如何找到template。在setting.py中,由TEMPLATE_LOADERS规定了一个template loader的元组,默认有两个是打开的:
django.template.loaders.filesystem.Loader
django.template.loaders.app_directories.Loader
第一个是说从文件系统中查找template,第二个是说从app的路径中找template。首先django会去由TEMPLATE_DIRS中指定的路径中查找template,如果没有找到,那么就会去各个app中的templates文件夹中查找,django会使用第一个符合条件的tempate。所以,一般都将template分为两个级别,一个是由TEMPLATE_DIRS指定的project级别的template,这个级别的优先被查找,一个就是各个app中的template,这个是第二级别。
这一部分主要讲了view的概念和使用。Django中根据请求的路径,会将请求路由给某个view来处理。那这里涉及到两个问题:
1.怎么路由的?
django根据URL进行正则匹配的,比如:
from django.conf.urls import patterns, include, url
from polls import views
urlpatterns = patterns('',
url(r'^choices/', views.index, name='index',
url(r'^polls/', include('polls.urls')),
url(r'^admin/', include(admin.site.urls)),
)
路径符合r'^choices/'的URL就会匹配第一个urlpatten,那么对应的请求就会被路由到views.index()方法来处理。那第二个include()是啥意思呢?它是view的一个集合,表示符合r'^polls/'的URL对继续往下路由,在polls.urls中继续进行匹配。可以在url()方法中指定name参数,即对这个urlpatten进行命名,方便在别的地方引用它。可以在include()中指定namespace参数,在不同的app中进行区分。
2.view怎么来处理的?
记住,view方法,总是返回一个HttpReponse对象,如:
from django.http import HttpResponse
from django.template import RequestContext, loader
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = RequestContext(request, {
'latest_poll_list': latest_poll_list,
})
return HttpResponse(template.render(context))
框架就是这样,跟你约定了很多东西,你要用它就必须遵守。虽然它也提供了很多快捷方式来简化你的代码,但是仍然要理解最底层的东西,否则会迷失了自己。在view中可以做你想做的任何事情,它就是用来实际做事情的,比如访问数据库,访问API,得到数据之后,将数据放在context中,传递给template去进行渲染。
另外就是Part 3还介绍了几个template的tag的用法,比如{% for %}, {% url %},这里重点说一下{% url %},它是和urlpattens中,定义urlpatten的时候,传递给url()的name参数配合使用的,比如{% url 'index' %},或者是 {% url 'detail' poll.id %}
当给urlpatten定义了namespace的时候,使用url tag的时候,可以指定namespace,如{% url 'polls:detail' poll.id %}
Part 4主要讲了两个方面的内容,一个是Form的使用,包括template怎么写,view怎么接受form表单的数据,另外一个是介绍了generic view的使用方法。
先说第一个,Form表单的作用是提交用户填写的数据到服务器端,这里template的form怎么写就不废话了,需要注意的是在view中怎么处理表单提交的数据,方法如下:
pk=request.POST['choice']
通过request这个HttpRequest对象拿。另外需要注意的一点是,一般form表单会向服务器提交数据,所以为了重复提交,form表单summit之后,都会重定向到另外一个url,而不是停留在form这个页面,那么此时返回的对象就不是HttpResponse了,而是HttpResponseRedirect对象,后者应该是前者的子类。
之后就是介绍了django中generic view的使用方法,先说generic view存在的意义:在一般的web开发中,都有一个非常常见的模式,就是从数据库中得到数据,然后到template中展现出来。django对这种模式做了封装,就是generic view,提供了ListView和DetailView等类做这些处理,具体怎么用,就不多说了,用法见文档generic view
Part 5介绍的是django的单元测试,这里就不细说了,不过那里面说的,why you need to create tests 可谓是经典。
Part 6 很简单,介绍了静态文件的使用方法,主要是介绍了AppDirectoriesFinder的原理,即在setting.py中,可以在STATICFILES_FINDERS中指定一些静态文件的查找方法,AppDirectoriesFinder就是其中一个,而且是默认的,它会到每一个app的static目录中查找静态文件。