第2章 Django 速成:构建一个Blog:

来源:互联网 发布:爱淘宝 编辑:程序博客网 时间:2024/06/11 20:31
第2章 Django 速成:构建一个Blog:2.1 创建项目:[root@node01 app]# pip install djangoDownloading/unpacking django  Downloading Django-1.11.5-py2.py3-none-any.whl (6.9MB): 6.9MB downloadedDownloading/unpacking pytz (from django)  Downloading pytz-2017.2-py2.py3-none-any.whl (484kB): 484kB downloadedInstalling collected packages: django, pytzSuccessfully installed django pytzCleaning up...[root@node01 app]# django-admin.py startproject mysite[root@node01 app]# lsmysite[root@node01 app]# cd mysite/[root@node01 mysite]# lsmanage.py  mysite[root@node01 mysite]# cd mysite/[root@node01 mysite]# ls__init__.py  settings.py  urls.py  wsgi.py除了__init__.py ,startproject命令还创建了以下三个文件:1.manage.py 文件是一个同这个Django项目一起工作的工具,你可以从它在目录列表中的权限里看到它是可以执行的。[root@node01 mysite]# ls -ltrtotal 8-rwxr-xr-x 1 root root  804 Sep  8 00:54 manage.pydrwxr-xr-x 2 root root 4096 Sep  8 00:54 mysite2.settings.py 文件包含了项目的默认设置,3.urls.py 文件在Django里叫URLconf,它是一个将URL模式映射到你应用程序上的配置文件。2.2 运行开发服务器;启动dev的命令如下:node2:/app/mysite#./manage.py runserverPerforming system checks...System check identified no issues (0 silenced).August 23, 2017 - 16:59:47Django version 1.11, using settings 'mysite.settings'Starting development server at http://127.0.0.1:8000/Quit the server with CONTROL-C.CommandError: "192.168.137.3" is not a valid port number or address:port pair.node2:/app/mysite#python manage.py runserver 192.168.137.3:8000Performing system checks...System check identified no issues (0 silenced).August 23, 2017 - 17:04:21Django version 1.11, using settings 'mysite.settings'Starting development server at http://192.168.137.3:8000/Quit the server with CONTROL-C.2.3 创建Blog应用: 有了项目以后,就可以在它下面创建应用(按Django的说法是"app")了。我们再次使用mange.py来创建这个blog appnode2:/app/mysite#./manage.py startapp blog node2:/app/mysite#这样就完成项目的创建了,现在我们在项目的目录下有了一个blog目录。node2:/app/mysite/blog#ls -ltrtotal 24-rw-r--r-- 1 root root  148 Aug 24 13:15 apps.py-rw-r--r-- 1 root root  128 Aug 24 13:15 views.py-rw-r--r-- 1 root root  122 Aug 24 13:15 models.py-rw-r--r-- 1 root root  125 Aug 24 13:15 tests.py-rw-r--r-- 1 root root    0 Aug 24 13:15 __init__.py-rw-r--r-- 1 root root  128 Aug 24 13:15 admin.pydrwxr-xr-x 2 root root 4096 Aug 24 13:15 migrationsnode2:/app/mysite/blog#和项目一样,app也是一个包,现在models.py和views.py 里还没有真正的代码,它们只是先占住位子而已。要告诉Django这个app是项目里的一部分,你需要去编辑settings.py文件(也称之为"配置文件").打开配置文件并在文件尾部找到INSTALLED_APPS元组。INSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',]Django 用INSTALLED_APPS来决定系统里不同部分的配置,包括自动化的admin应用以及测试框架。2.4 设计你的Model:现在我们来到了这个基于Django的blog应用的核心部分:models.py文件,这是我们定义blog数据结构的地方。根据DRY原则,Django会尽量利用你提供给应用程序的model信息。我们先来创建一个基本的model,看看Django用这个信息为我么做了点什么:node2:/app/mysite/blog#cat models.py # -*- coding: utf-8 -*-from django.db import models#  Create your models here.class BlogPost (models.Model):     title  =  models.CharField(max_length=150)     body  =  models. TextField()     timestamp  =  models .DateTimeField()这是一个完整的model,代表了一个有3个变量的"BlogPost"对象。(严格来说应该有4个,Django会默认在每个model自动加上一个自增的,唯一的id变量)。这个新建的BlogPost类是django.db.models.Module的一个子类。这是Django为数据model准备和标准基类,它是Django强大的对象关系映射(ORM)系统的核心。使用数据库服务器:DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'pydb','USER': 'root','PASSWORD': '1234567','HOST': '192.168.137.3','PORT': '3306',}}现在你可以告诉Django用你提供的连接信息去连接数据库并且设置应用程序所需的表:python manage.py makemigrationspython manage.py migrateclass BlogPost (models.Model):     title  =  models.CharField(max_length=150)     body  =  models. TextField()     timestamp  =  models .DateTimeField()mysql> desc blog_blogpost    -> ;+-----------+--------------+------+-----+---------+----------------+| Field     | Type         | Null | Key | Default | Extra          |+-----------+--------------+------+-----+---------+----------------+| id        | int(11)      | NO   | PRI | NULL    | auto_increment || title     | varchar(150) | NO   |     | NULL    |                || body      | longtext     | NO   |     | NULL    |                || timestamp | datetime(6)  | NO   |     | NULL    |                |+-----------+--------------+------+-----+---------+----------------+4 rows in set (0.01 sec)当你执行syncdb命令时,Django会查找INSTALLED_APPS里的每一个models.py文件,并找到的每一个model都创建一张数据库表。node2:/app/mysite#python manage.py migrateOperations to perform:  Apply all migrations: admin, auth, blog, contenttypes, sessionsRunning migrations:  Applying contenttypes.0001_initial... OK  Applying auth.0001_initial... OK  Applying admin.0001_initial... OK  Applying admin.0002_logentry_remove_auto_add... OK  Applying contenttypes.0002_remove_content_type_name... OK  Applying auth.0002_alter_permission_name_max_length... OK  Applying auth.0003_alter_user_email_max_length... OK  Applying auth.0004_alter_user_username_opts... OK  Applying auth.0005_alter_user_last_login_null... OK  Applying auth.0006_require_contenttypes_0002... OK  Applying auth.0007_alter_validators_add_error_messages... OK  Applying auth.0008_alter_user_username_max_length... OK  Applying blog.0001_initial... OK  Applying sessions.0001_initial... OK设置admin:manage.py createsuperusernode2:/app/mysite#manage.py createsuperuser-bash: manage.py: command not foundnode2:/app/mysite#./manage.py createsuperuserUsername (leave blank to use 'root'): adminEmail address: admin@163.comPassword: Password (again): The password is too similar to the email address.This password is too short. It must contain at least 8 characters.This password is too common.Password: Password (again): Superuser created successfully.自动化的后台应用程序admin称的上是Django "皇冠上的明珠".设置完app以后,我们需要为它指定一个URL这样才能访问它,你应该已经注意到了在自动生成的urls.py中的这样两行代码:1.8以上的版本:from django.conf.urls import urlfrom django.contrib import adminfrom blog import views as blog_viewurlpatterns =( url(r'^admin/', admin.site.urls),url(r'^index/$',blog_view.index),)最后,你的应用根据官方文档修改了blog / views.py里的内容,可以正常显示了from __future__ import unicode_literals# from django.shortcuts import render, render_to_responsefrom .models import *# Create your views here.from django.http import HttpResponsefrom django.template import loaderdef index(req):# get all blogpost objectsblog_list = BlogPost.objects.all()template = loader.get_template('index.html')context = {'blog_list': blog_list}return HttpResponse(template.render(context, req))打开:node2:/app/mysite/blog#cat models.py# -*- coding: utf-8 -*-from django.db import models#  Create your models here.class BlogPost (models.Model):     title  =  models.CharField(max_length=150)     body  =  models. TextField()     timestamp  =  models .DateTimeField()node2:/app/mysite#cat blog/views.py# -*- coding: utf-8 -*-from __future__ import unicode_literals# from django.shortcuts import render, render_to_responsefrom .models import *# Create your views here.from django.http import HttpResponsefrom django.template import loaderdef index(req):# get all blogpost objects  blog_list = BlogPost.objects.all()  template = loader.get_template('index.html')  context = {  'blog_list': blog_list  }  return HttpResponse(template.render(context, req))node2:/app/mysite#./manage.py runserver 192.168.137.3:8000Performing system checks...System check identified no issues (0 silenced).August 24, 2017 - 06:45:36Django version 1.11, using settings 'mysite.settings'Starting development server at http://192.168.137.3:8000/Quit the server with CONTROL-C.给你的帖子取一个名字然后往里填一点内容,至于时间戳,2.8 建立Blog的公共部分:完成我们应用的数据库部分和admin部分后,现在来看看面向公众的页面部分。从Django的角度来说,一个页面具有3个典型的组件:1.一个模板(template),模块负责将传递进来的信息显示出来(HTML页面)2.一个视图(view)函数,它负责获取要显示的信息,通常都是从数据库获得3.一个URL模式,它用来把收到的请求和你的视图函数匹配,有时也会向视图传递一些参数。创建模板:Django的模板语言相当简单,我们直接来看代码,这是一个简单的显示单个blog帖子的模板:node2:/app/mysite/blog/templates#cat archive.html {%for post in posts%}<h2?{{post.title}}</h2><p>{{post.timestamp}}</p><p>{{post.body}}</p>{% endfor %}它就是一个HTML (虽然Django模块可以用于任何形式的输出)加上一些大括号的特殊模板标签。这些是标量标签(variable tag),用于显示传递给模板的数据。在变量标签里,你可以用Python风格的dotted-notation(点记号)来访问传递给模板的对象的属性。例如,这里假设你传递了一个叫"post"的BlogPost对象。创建一个视图函数: 现在我们来编写一个从数据库读取所有blog帖子的视图函数,并且我们的模板将它们显示出来。打开blog/views.py文件并输入:node2:/app/mysite/blog#cat views.py# -*- coding: utf-8 -*-from __future__ import unicode_literals# from django.shortcuts import render, render_to_responsefrom .models import *# Create your views here.from django.http import HttpResponsefrom django.template import loaderdef index(req):# get all blogpost objects  blog_list = BlogPost.objects.all()  template = loader.get_template('archive.html')  context = {  'blog_list': blog_list  }  return HttpResponse(template.render(context, req))node2:/app/mysite/blog#vim views.py# -*- coding: utf-8 -*-from __future__ import unicode_literals# from django.shortcuts import render, render_to_responsefrom .models import *# Create your views here.from django.http import HttpResponsefrom django.template import loaderdef index(req):# get all blogpost objects  blog_list = BlogPost.objects.all()  template = loader.get_template('index.html')  context = {  'blog_list': blog_list  }  return HttpResponse(template.render(context, req)){% extends "base.html" %}  {% block content %}      {% for post in blog_list %}      <h2>{{  post.title }}</h2>      <p>{{ post.timestamp | date:"1,F jS"}}</p>      <p>{{ post.body }}</p>      {% endfor %}  {% endblock %}url(r'^index/$',blog_view.index), 调用blog下的view类的index方法  --入口node2:/app/mysite/blog#vim views.py# -*- coding: utf-8 -*-from __future__ import unicode_literals# from django.shortcuts import render, render_to_responsefrom .models import *# Create your views here.from django.http import HttpResponsefrom django.template import loaderdef index(req):# get all blogpost objects  blog_list = BlogPost.objects.all()  template = loader.get_template('index.html')  context = {  'blog_list': blog_list  }  return HttpResponse(template.render(context, req))blog_list = BlogPost.objects.all() :获取数据库里面所拥有BlogPost对象render_to_response()返回一个页面(index.html),顺带把数据库中查询出来的所有博客内容(blog_list)也一并返回。把响应内容给模板Index.html按日期排序:node2:/app/mysite/blog#cat models.pyfrom django.db import modelsfrom django.contrib import admin# Create your models here.class BlogPost(models.Model):    title = models.CharField(max_length = 150)    body = models.TextField()    timestamp = models.DateTimeField()    class Meta:      ordering =('-timestamp',)通过模板过滤器格式时间戳:虽然时间戳很好用,但是它的ISO8601格式却有点怪异。我们现在用Django模板系统里另一个很酷的特性:过滤器(filter)来把它弄得人性化一点:


 
原创粉丝点击