Django1.8教程——从零开始搭建一个完整django博客(一)

第一个Django项目将是一个完整的博客网站。它和我们博客园使用的博客别无二致,一样有分类、标签、归档、查询等功能。如果你对Django感兴趣的话,这是一个绝好的机会。该教程将和你一起,从零开始,搭建一个属于你自己的Django博客站点。

事不宜迟,让我赶快开始吧!

创建你的第一个Django项目

Django提供了一个命令,可以让你轻松地创建初始Django项目文件结构。从你的终端运行以下命令:

django-admin startproject mysite 

这将会创建一个名为mysite的Django项目。

让我们看看Django项目的结构:

|- mysite/   
	|- manage.py   
	|- mysite/
		|- __init__.py     
		|- settings.py     
		|- urls.py     
		|- wsgi.py
  • manage.py: 一个命令行交互文件,用于显示项目的运行情况,不用对这个文件做任何修改。

  • mysite/: 你项目的目录下包含着以下文件:

    • __init__.py : 空的Python文件,用来告诉Python将这个项目目录视为一个Python模块。
    • settings.py : 项目的配置和设置文件,用命令行生成的Django项目会自动生成默认配置。
    • urls.py : URL配置文件,每一行URL都对应一个相应的视图(view)
    • uwsgi.py : 配置您的项目,让它作为一个WSGI程序运行。

生成的settings.py文件默认情况下包括SQLite数据库设置与Django app列表,我们需要在数据库中创建初始应用程序的表。

打开终端并运行下面的命令:

cd mysite 
python manage.py migrate

你可以看到以下输出:

Rendering model states... DONE
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... 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 sessions.0001_initial... OK

至此,初始Django app的表已经创建完毕。

运行开发者服务器

Django会用自带的轻量级Web服务器来运行你的代码,不需要花费大量的时间配置生产服务器。当你运行Django开发服务器,它会检查代码中的变化,自动重新加载。把你从手动重启服务器的繁琐过程中解放出来。然而,它可能不会注意到一些操作,比如向项目添加新的文件,在这些情况下,你将不得不手动重新启动服务器。

从项目的根目录中输入以下命令:

python manage.py runserver

你可以看到以下输出:

Performing system checks...
System check identified no issues (0 silenced).
November 5, 2015 - 19:10:54
Django version 1.8.6, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.

现在,打开浏览器输入HTTP://127.0.0.1:8000/。看到这个页面就说明运行成功,如图所示:

你也可以自定义Django开发服务器主机和端口,或者告诉它你想加载不同的设置文件。例如,您可以运行manage.py命令如下:

python manage.py runserver 127.0.0.1:8001 \ -- settings=mysite.settings

这是方便处理多个环境,需要不同设置的情况。请记住,此服务器只用于开发,不适合用于生产使用。为了部署Django的生产环境,你应该使用一个真正的Web服务器,如Apache,gunicorn应用,或uWSGI。让其作为一个网络服务器的网关接口运行它(WSGI)

项目设置

让我们打开settings.py文件,看一看我们的项目配置。

其中Django常用设置包含在这个文件当中,但这些只是Django设置的一部分。所有设置可以在此看到:https://docs.djangoproject.com/en/1.8/ref/settings/.

  • DEBUG:一个布尔值,该布尔函数用以打开项目的调试模式。如果设置为true,Django会显示详细的错误页面。当你移动到一个生产环境,记得必须设置它为False。不要将网站以调试模式部署到生产中,这样会暴露你的项目的敏感数据。

  • ALLOWED_HOSTS:在调试模式或正在运行测试时,这个选项不起作用。一旦你关闭调试模式,并将你的网站布置在正式的生产环境,就必须在settings.py中添加部署环境的域名/主机,以便允许服务器运行Django站点。

  • INSTALLED_APPS :这个设置告诉Django哪些app是启用的。默认情况下,Django包含下面application:

    • django.contrib.admin: Django管理站点.
    • django.contrib.auth: Django认证模块.
    • django.contrib.contenttypes: Django内容类型框架.
    • django.contrib.sessions: Django会话框架.
    • django.contrib.messages: Django消息传递框架.
    • django.contrib.staticfiles: Django管理静态文件的框架.
  • MIDDLEWARE_CLASSES :一个元组,包含需要执行的中间件。

  • DATABASES:是一个用于在项目中使用的,包含所有数据库的字典。默认的配置使用sqlite3数据库。

  • LANGUAGE_CODE:为Django项目定义默认的使用语言。

如果你对Django的设置还不是十分了解,不要担心。在接下来的学习中,你更加了解Django的相关设置。

项目(project)与应用(application)

在本书中,你可能会经常看到项目(project)应用(application)这两个Django术语。项目通常是指由你生成的Django站点程序以及与站点相关的设置。而应用通常是指包含模块(models.py)、视图(views.py)、模板(template)和链接(url.py)的一个Python模块。应用和框架之间相互作用,提供一系列特定的功能。并且,有些应用可以在不同的项目间重用。比如博客、论坛可以用在其他的项目中。

创建一个应用

现在让我们来创建你的第一个Django的应用。我们将从零开始创建一个博客应用。找到项目的根目录,运行以下命令:

python manage.py startapp blog

这就创建了一个app的基本结构:

|- blog/
	|- __init__.py     
	|- admin.py     
	|- migrations/
    	|- __init__.py     
	|- models.py     
	|- tests.py     
	|- views.py

admin.py: 用来将你的app注册到Django的管理站点,只有注册过的app才能在Django管理后台进行设置与管理。

migrations:这个目录包含app数据库的迁移记录。migrations允许Django来跟踪你的模型的变化和相应的数据库同步。

models.py:app数据模型。所有的Django应用程序都需要有一个models.py文件,但这个文件可以是空的。

tests.py: 可以将测试添加到该文件。

views.py:视图文件用来设置模型的逻辑。每个视图接收一个HTTP请求,并返回相应的响应。

设计Blog应用的数据模型

我们将为我们的博客定义初始数据模型。一个模型是一个Python类,并且是django.db.models.model的子类。

其中模型中的每个属性代表一个数据库字段。Django为定义在models.py的每个模型都建立对应的模型表。当你创建一个模型,Django提供API以方便查询数据库。

首先,我们将定义一个模型。将下面几行添加到博客应用models.py文件:

from django.db import models 
from django.utils import timezone 
from django.contrib.auth.models import User

class Post(models.Model):     
	STATUS_CHOICES = (
        ('draft', 'Draft'),
        ('published', 'Published'),
    )
    title = models.CharField(max_length=250)     
	slug = models.SlugField(max_length=250, unique_for_date='publish')     
	author = models.ForeignKey(User, related_name='blog_posts')     
	body = models.TextField()
    publish = models.DateTimeField(default=timezone.now)     
	created = models.DateTimeField(auto_now_add=True)     
	updated = models.DateTimeField(auto_now=True)     
	status = models.CharField(max_length=10,                               
	choices=STATUS_CHOICES, default='draft')

    class Meta:         
		ordering = ('-publish',)

    def __str__(self):         
		return self.title

这是我们博客的基本模型。让我们看看刚刚定义的这个模型的字段:

  • title:这是文章标题属性。CharField是字符字段,将会转化成SQL数据库varchar列。

  • slug: slug属性经常被用于URLs,slug只包含字母。数字、还有下划线。通过使用slug属性,我们可以轻而易举的为我们的文章创建优雅的、SEO友好的链接。我们添加了unique_for_date参数,这表示每一个由模型创造的文章实例都有唯一的slug属性,并且不存在相同的slug字段。

注:比如我们发表了一篇文章,标题是:Django中文教程,那么该怎么设计这篇文章的url呢?我们可以直接将标题作为url地址:
http://www.landsblog.com/blog/category/Django中文教程
但url传输过程会经过urlencode编码
结果就变成:
http%3a%2f%2fwww.landsblog.com%2fartical%2fDjango%e4%b8%ad%e6%96%87%e6%95%99%e7%a8%8b,一长串16进制字符串,既不美观也不容易被Spider识别,因此用slug来代替标题,为每一篇文章设定一个简短的,易于识别的标题。比如在该例子中,可以将slug设置成django_course,url设计成:
http://www.landsblog.com/blog/category/djangodoc
是不是美观了许多?

  • author:此字段是外键(ForeignKey)。该字段定义了一个一对多的关系。我们告诉Django,每篇文章都只有一个作者,但是一个作者可以写多篇文章。对于Author字段,Django将会用相关联的模型(也就是User模型)的主键(PrimaryKey)来创建一个外键,建立一个从Post到User的映射关系。在本例中,我们依赖Django认证系统的User模型作为Blog模型的关联模型。同时我们定义related_name属性,用以指向从User到Post的映射关系。

  • body:文章的主体内容,将会转化成SQL数据库中的文本列。

  • publish:这表明文章的发表日期。我们使用表示当前时间的timezone.now方法作为默认值。

  • created:这表明文章被创建的日期。由于我们使用的是auto_now_add参数,创建对象时将会使用当前时间自动保存。

  • updated:显示文章最后一次更新时间。由于我们使用的是auto_now参数,保存修改对象的时候,日期会自动更新。

  • status:这是一个显示文章状态的属性。我们使用一个选择参数,所以这个status的值只能被设置为一个给定的选择。

正如你所见,Django自带了许多类型的字段(field),以便你能够随心所欲定义自己的模型。

模型类中的元类(Meta)包含元数据,ordering属性定义了文章的排序顺序。当我们查询数据库,这些文章将按照发布顺序降序排列。

Django使用__str__()方法,用文章的标题来代替名称'object'。如果不定义__str__()方法,模型生成的实例对象将会以’object‘这个名字显示在django的管理站点,不宜于管理和修改。

注意:如果你使用的是Python2.x版本,则用__unicode__()来代替__str__()

因为我们要处理的日期,需要安装pytz模块。这个模块提供了Python的时区定义,是SQLite正常工作必不可少的模块。打开终端输入下列命令:

pip install pytz

Django自带支持时区功能,你可以在项目的设置文件中,通过设置USE_TZ来激活时区设置。当你通过命令行创建Django项目的时候,USE_TZ默认设为True。

激活你的应用

为了让Django持续跟踪我们的应用变化,为模型创建数据库表,我们必须激活它。为此,编辑settings.py文件,并在installed_apps设置中添加blog模型。它应该看起来像这样:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
)

现在Django已经激活了blog app

创建和应用迁移

为我们的模型在数据库中创建一个数据表。Django自带数据迁移系统来跟踪你的模型变化,并同步至数据库当中。迁移命令(migration)将会对installed_apps设置中的所有应用进行迁移,始终保持与应用的同步。

首先,需要为我们的模型创建一个迁移记录的列表:

python manage.py makemigrations blog

将会看到以下输出:

You should get the following output:
Migrations for 'blog':
	0001_initial.py:
	- Create model Post

Django刚刚在migrations目录下创建了0001_initial.py文件,你可以打开看看这个迁移文件究竟是什么样子?

Django将会执行迁移文件中的SQL代码,来创建blog模型的数据表。sqlmigrate命令可以看到SQL代码并没有立即执行。

python manage.py sqlmigrate blog 0001

将会有如下输出:

BEGIN;
CREATE TABLE "blog_post" ("id" integer NOT NULL PRIMARY KEY 
AUTOINCREMENT, "title" varchar(250) NOT NULL, "slug" varchar(250) NOT 
NULL, "body" text NOT NULL, "publish" datetime NOT NULL, "created" datetime NOT NULL, "updated" datetime NOT NULL, "status" varchar(10) NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id"));
CREATE INDEX "blog_post_2dbcba41" ON "blog_post" ("slug");
CREATE INDEX "blog_post_4f331e2f" ON "blog_post" ("author_id");
COMMIT;

根据使用的数据库的不同,你可能会看到不同的输出数据。上面的输出使用的是SQLite。你可以看到Django生成的数据表名称是由app名称与小写的模型名称组合而成(blog_post),你也可以在元类中使用db_table参数来自定义数据表的名称。Django自动为每一个模型创建主键(Primary_key),当然你也可以在模型的任一属性中添加primary_key=True来自定义主键。

运行以下命令来同步数据库:

python manage.py migrate

得到以下显示:

Applying blog.0001_initial... OK

我们刚刚为installed_apps列表中的所有应用创建了数据表,包括了我们定义的blog应用。现在,数据库反映了我们的模型的当前状态。

如果你对模型进行添加,删除,修改字段等操作,或者你添加了新的模型,都必须用makemigrations命令来创建一个新的迁移列表。迁移文件将会持续跟踪模型的变化,然后你需要运行migrate命令来保证数据库与模型的同步。

原文链接:http://www.landsblog.com/blog/content/djangoexamplecreate
更多教程:http://www.landsblog.com/blog/tag/django

posted @ 2016-07-28 22:01  Data&Truth  阅读(12862)  评论(0编辑  收藏  举报