Django创建一个简单的blog
1. 使用django-admin.py 创建mysite项目
sunny@sunny-ThinkPad-T450:~/PycharmProjects$ django-admin.py startproject mysite
2. 进入项目目录中,启动服务器,测试连通性
sunny@sunny-ThinkPad-T450:~/PycharmProjects$ cd mysite/ sunny@sunny-ThinkPad-T450:~/PycharmProjects/mysite$ ./manage.py runserver 0.0.0.0:8000 Validating models... 0 errors found April 29, 2016 - 06:20:27 Django version 1.6.5, using settings 'mysite.settings' Starting development server at http://0.0.0.0:8000/ Quit the server with CONTROL-C. [29/Apr/2016 06:20:33] "GET / HTTP/1.1" 200 1757
3. 创建blog应用
sunny@sunny-ThinkPad-T450:~/PycharmProjects/mysite$ ./manage.py startapp blog sunny@sunny-ThinkPad-T450:~/PycharmProjects/mysite$ tree . ├── blog │ ├── admin.py │ ├── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py ├── manage.py └── mysite ├── __init__.py ├── __init__.pyc ├── settings.py ├── settings.pyc ├── urls.py ├── urls.pyc ├── wsgi.py └── wsgi.pyc 2 directories, 14 files
4. 告诉Django这个app是项目的一部分,编辑setting.py配置文件
INSTALLED_APPS = (
'django.contrib.auth', 'django.contrib.admin','django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', #添加的部分,注意后面的,号 )
5. 设计Model
基于Django的blog应用的核心部分:models.py。这是定义blog数据结构的地方。根据DRY(代码不重复)原则,Django会尽量利用你提供给应用程序的model信息。
5.1 在blog包下的models.py下编写下面代码:设置了3个变量,有一个默认的id变量,是自增的。(其实就是数据库列)
from django.db import models class BlogPost(models.Model): title = models.CharField(max_length=150) body = models.TextField() timestamp = models.DateTimeField()
5.2 设置数据库(使用的是MySQL)
Django中默认使用的是SQLite,我在这里使用的是MySQL,则需要在配置文件中修改数据库的基本信息(首先创建数据库,名为djangodb):
DATABASES = { 'default':{ 'ENGINE':'django.db.backends.mysql', 'NAME':'djangodb', 'USER':'root', 'PASSWORD':'××××××',#连接数据库服务器的密码 'HOST':'localhost', 'PORT':'3306', } }
5.3 创建表
sunny@sunny-ThinkPad-T450:~/PycharmProjects/mysite$ ./manage.py syncdb
当执行syncdb命令时,Django会查找INSTALLED_APPS里的每一个models.py文件,并为找到的每一个model都创建一张数据表。对照上图与配置文件INSTALLED_APPS中的参数,可以看到syncdb为每一个app都创建了一个或多个表。
syncdb命令的输出除了上图,还有
You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (leave blank to use 'sunny'): Email address: Password: Password (again): Superuser created successfully. Installing custom SQL ... Installing indexes ... Installed 0 object(s) from 0 fixture(s)
这才是完整输出。这之后,我在auth系统里建立了一个超级用户,便于加入Django的自动admin应用。
5.4 设置自动admin应用
自动化的后台应用程序admin称得上是Django的明珠,为WEB应用创建简单CRUD接口的福音。由于这不是Django里的必要组件,则必须在setting.py文件里指定使用它。需要在INSTALLED_APPS元组里的'django.contrib.auth'下面添加一行'django.contrib.admin';
每次往项目中添加新的应用后,都要运行一下syncdb命令以确保它所需的表已经在数据库里创建。
查看urls.py里的代码:
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Examples: # url(r'^$', 'mysite.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), #告诉Django去加载默认的admin站点,这是被用于contrib admin应用程序的一个特殊对象。 )
之后,需要将编辑的应用程序告诉Django要在admin窗口里显示哪一个model以供编辑。编辑blog中models.py中的代码,只需要定义之前提到的默认admin站点,并向其注册BlogPost model就行:
from django.db import models from django.contrib import admin class BlogPost(models.Model): title = models.CharField(max_length=150) body = models.TextField() timestamp = models.DateTimeField() admin.site.register(BlogPost)
6. 使用admin
运行./manage.py runserver 命令,然后在浏览器里输入http://127.0.0.1:8000/admin/,则会出现一个登陆窗口
使用超级用户的用户名和密码登陆之后,会出现下面的界面:
点击BlogPost后面的添加,里面会出现model中的三个元素title、 body、timestampe,添加完后点击save;
在models.py文件里再添加一个BlogPostAdmin类,并将它添加到注册代码中去:
from django.db import models from django.contrib import admin class BlogPost(models.Model): title = models.CharField(max_length=150) body = models.TextField() timestamp = models.DateTimeField() class BlogPostAdmin(admin.ModelAdmin): list_display = ('title','timestamp') admin.site.register(BlogPost,BlogPostAdmin)
根据BlogPostAdmin类中的list_display变量(title,timestamp)来生成输出;
7. 建立Blog的公共部分
这部分是面向公众的页面部分。从Django的角度来说,一个页面具有三个典型的组件:
- 一个模板(template),负责将传递进来的信息显示出来(用一种类似Python字典的对象Context)。
- 一个视图(view),负责获取要显示的信息,通常都是从数据库里取得。
- 一个URL模式,用来把收到的请求和视图函数匹配,有时会向视图传递一些参数。
7.1 创建模板(template)
{% for post in posts %} <h2>{{ post.title }}</h2> <p>{{ post.timestamp }}</p> <p>{{ post.body }}</p> {% endfor %}
类似html语言,假设传递了一个叫post的BlogPost对象,分别从BlogPost中的title、timestamp、body中提取出元素。将这些代码保存到archive.html文件中,并将该文件放到blog目录下的templates目录中。大括号中的模板标签叫做变量标签,用于显示传递给模板的数据。
7.2 创建一个视图函数
在views.py文件中,编写一个从数据库中读取所有blog帖子的视图函数,并用模板将其显示出来;
from django.template import loader,Context from django.http import HttpResponse from blog.models import BlogPost # Create your views here.
#每个Django视图函数都将django.http.HttpRequest对象作为它的第一个参数,
#它还可以通过URLconf接受其他参数 def Archive(request):
#BlogPost类为django.db.model.Model的一个子类,这样,该类就获得了Django对象关系映射的
#的全部力量。该行主要是获取数据库里的所有BlogPost对象 posts = BlogPost.objects.all()
#根据Django模板的名字就能创建模板的对象t。 t = loader.get_template("archive.html")
#Django模板渲染的数据是由一个字典类的对象context提供的,这里的context c只有一对键和值 c = Context({'posts':posts})
#每个视图函数都会返回一个django.http.HttpResponse对象。给其构造函数传递一个字符串。 return HttpResponse(t.render(c))
7.3 创建一个URL模式
可以直接在mysite/urls.py里创建所需要的URL模式,但是那样只会在项目和app之间制造混乱的耦合。Blog app还可以用在别的地方,所以最好是它能为自己的URL负责。
(1)在mysite/urls.py里添加一个指向blog的url,如下,这会捕捉任何以blog/开始的请求,并把它们传递给一个你马上要新建的URLconf:
url(r'^blog/',include('mysite.blog.urls')),
(2)在blog应用程序包中定义URL。创建一个urls.py文件,即mysite/blog/urls.py(正好与上面的路径对应):
from django.conf.urls import patterns,url from blog.views import archive urlpatterns = patterns('', url(r'^$',archive), #传递的不是函数名字,而是一个first-class的函数对象. )
7.4 查看效果
./manage.py runserver 0.0.0.0:8000
查看http://127.0.0.1:8000/blog/
8.显示有点丑,润色
在templates里面创建一个基础模板,然后在这之上扩展出其他特定模板来。基础模板base.html如下:
<!DOCTYPE html> <html lang="en"> <style type="text/css"> body{ color:#efd; background: #453; padding: 0 5em; margin: 0 } h1{ padding: 2em 1em; background: #675; } h2{ color: #bf8; border-top: 1px dotted #fff; margin-top: 2em; } p{ margin: 1em 0; } </style> <body> <h1>sunny's blog</h1> {% block content %} #define a sub_template,can change named block {% endblock %} </body> </html>
修改archive.html模板,让它引用新的基础模板及其content块:
{% extends "base.html" %}#新增 {% block content %}##新增 {% for post in posts %} <h2>{{ post.title }}</h2> <p>{{ post.timestamp|date:"l,F jS" }}</p> ##这是为了修改显示时间而增加的过滤器filter <p>{{ post.body }}</p> {% endfor %} {% endblock %} ##新增
blog一般按日期进行排序的,有几种做法:一是在model里加入一个默认的顺序,二是在视图代码里的BlogPost.objects().all()上添加排序功能。在此修改的是model,在BlogPost类里添加一个Meta的嵌套类,
##order method class Meta: ordering = ('-timestamp','title')
9. 总结
几个Django优雅简洁的特性:
1)内置的Web服务器能让开发工作自给自足,同时它能在代码被修改时自动重新加载代码;
2)数据模型的创建采用纯Python方式完成,不用编写维护任何SQL代码或XML描述文件;
3)自动化的admin应用程序,提供了完整的内容编辑特性,甚至非技术北京的用户也能使用。
4)模板系统,可以用来生成html、CSS、JavaSript以及任何文本输出格式;
5)模板过滤器,可以在不解除应用程序商业逻辑的前提下修改表示层的数据显示功能(比如日期);
6)URLconf系统,在给予URL设计极大灵活性的同时还能将应用程序特定的URL部分保留在其所属的应用程序内部;