《Django By Example》第一章 学习笔记

时间:2023-03-10 03:53:17
《Django By Example》第一章 学习笔记

首先看了下目录,在这章里 将会学到

  • 安装Django并创建你的第一个项目
  • 设计模型(models)并且生成模型(model)数据库迁移
  • 给你的模型(models)创建一个管理站点
  • 使用查询集(QuerySet)和管理器(managers)
  • 创建视图(views),模板(templates)和URLs
  • 给列表视图(views)添加页码
  • 使用Django内置的视图(views)

首先我们要安装Django

Django 需要在python 2.7或者3版本上才能更好的工作,书本上使用的是python3 这里也使用python3

创建一个独立的python环境

virtualenv 请用pip下载 pip install virtualenv

 virtualenv django_by_example -p python3
这句话里的意思是,创建一个虚拟环境,并指定用python3版本(如果您的计算里有python2,默认是用python2)
然后进入虚拟环境
source django_by_example/bin/activate
cd django_by_example #进入路径
django-admin startproject mysite     #创建项目

  《Django By Example》第一章 学习笔记

这是目录树

让我们来了解一下这些文件:

  • manage.py:一个实用的命令行,用来与你的项目进行交互。它是一个对django-admin.py工具的简单封装。你不需要编辑这个文件。
  • mysite/:你的项目目录,由以下的文件组成:
    • init.py:一个空文件用来告诉Python这个mysite目录是一个Python模块。
    • settings.py:你的项目的设置和配置。里面包含一些初始化的设置。
    • urls.py:你的URL模式存放的地方。这里定义的每一个URL都映射一个视图(view)。
    • wsgi.py:配置你的项目运行如同一个WSGI应用。

默认生成的settings.py文件包含一个使用一个SQLite数据库的基础配置以及一个Django应用列表,这些应用会默认添加到你的项目中。我们需要为这些初始应用在数据库中创建表。

python manager runserver #运行开发服务器

现在,在浏览器中打开 http://127.0.0.1:8000/ ,你会看到一个告诉你项目成功运行的页面,如下图所示:

《Django By Example》第一章 学习笔记

你可以指定Django在定制的host和端口上运行开发服务,或者告诉它你想要运行你的项目通过读取一个不同的配置文件。例如:你可以运行以下 manage.py命令:

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

接下来是Setting 里面的一些参数的作用

  • 或者运行测试的时候不会起作用(译者注:最新的Django版本中,不管有没有开启debug模式该设置都会启作用)。一旦你准备部署你的项目到生产环境并且关闭了debug模式,为了允许访问你的Django项目你就必须添加你的域或host在这个设置中。
  • INSTALLED_APPS 这个设置你在所有的项目中都需要编辑。这个设置告诉Django有哪些应用会在这个项目中激活。默认的,Django包含以下应用:
    • django.contrib.admin:这是一个管理站点。
    • django.contrib.auth:这是一个权限框架。
    • django.contrib.contenttypes:这是一个内容类型的框架。
    • django.contrib.sessions:这是一个会话(session)框架。
    • django.contrib.messages:这是一个消息框架。
    • django.contrib.staticfiles:这是一个用来管理静态文件的框架
  • MIDDLEWARE_CLASSES 是一个包含可执行中间件的元组。
  • ROOT_URLCONF 指明你的应用定义的主URL模式存放在哪个Python模块中。
  • DATABASES 是一个包含了所有在项目中使用的数据库的设置的字典。里面一定有一个默认的数据库。默认的配置使用的是SQLite3数据库。
  • LANGUAGE_CODE 定义Django站点的默认语言编码。

项目和应用

在Django中,一个项目被认为是一个安装了一些设置的Django;一个应用是一个包含模型(models),视图(views),模板(templates)以及URLs的组合。应用之间的交互通过Django框架提供的一些特定功能,并且应用可能被各种各样的项目重复使用。你可以认为项目就是你的网站,这个网站包含多个应用,例如blog,wiki或者论坛,这些应用都可以被其他的项目使用

python manager startapp blog #创建应用
tree #查看目录结构
blog/
__init__.py
admin.py
migrations/
__init__.py
models.py
tests.py
views.py

这些文件的含义

  • admin.py: 在这儿你可以注册你的模型(models)并将它们包含到Django的管理页面中。使用Django的管理页面是可选的。
  • migrations: 这个目录将会包含你的应用的数据库迁移。Migrations允许Django跟踪你的模型(model)变化并因此来同步数据库。
  • models.py: 你的应用的数据模型(models)。所有的Django应用都需要拥有一个models.py文件,但是这个文件可以是空的。
  • tests.py:在这儿你可以为你的应用创建测试。
  • views.py:你的应用逻辑将会放在这儿。每一个视图(view)都会接受一个HTTP请求,处理该请求,最后返回一个响应。

现在我们来创建一个Model

#coding:utf-8
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)
crated = 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

这就是我们给blog帖子使用的基础模型(model)。让我们来看下刚才在这个模型(model)中定义的各个字段含义:

  • title: 这个字段对应帖子的标题。它是CharField,在SQL数据库中会被转化成VARCHAR。
  • slug:这个字段将会在URLs中使用。slug就是一个短标签,该标签只包含字母,数字,下划线或连接线。我们将通过使用slug字段给我们的blog帖子构建漂亮的,友好的URLs。我们给该字段添加了unique_for_date参数,这样我们就可以使用日期和帖子的slug来为所有帖子构建URLs。在相同的日期中Django会阻止多篇帖子拥有相同的slug。
  • author:这是一个ForeignKey。这个字段定义了一个多对一(many-to-one)的关系。我们告诉Django一篇帖子只能由一名用户编写,一名用户能编写多篇帖子。根据这个字段,Django将会在数据库中通过有关联的模型(model)主键来创建一个外键。在这个场景中,我们关联上了Django权限系统的User模型(model)。我们通过related_name属性指定了从UserPost的反向关系名。我们将会在之后学习到更多关于这方面的内容。
  • body:这是帖子的主体。它是TextField,在SQL数据库中被转化成TEXT
  • publish:这个日期表明帖子什么时间发布。我们使用Djnago的timezonenow方法来设定默认值。This is just a timezone-aware datetime.now(译者注:这句该咋翻译好呢)。
  • created:这个日期表明帖子什么时间创建。因为我们在这儿使用了auto_now_add,当一个对象被创建的时候这个字段会自动保存当前日期。
  • updated:这个日期表明帖子什么时候更新。因为我们在这儿使用了auto_now,当我们更新保存一个对象的时候这个字段将会自动更新到当前日期。
  • status:这个字段表示当前帖子的展示状态。我们使用了一个choices参数,这样这个字段的值只能是给予的选择参数中的某一个值。(译者注:传入元组,比如(1,2),那么该字段只能选择1或者2,没有其他值可以选择)

就像你所看到的的,Django内置了许多不同的字段类型给你使用,这样你就能够定义你自己的模型(models)。通过访问 https://docs.djangoproject.com/en/1.8/ref/models/fields/ 你可以找到所有的字段类型。

激活应用

在INSTALLED_APPS 中添加blog

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

排序也会影响功能,后面看书再说..

数据库迁移

python manage.py makemigrations blog
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Post
python manage.py sqlmigrate blog 0001
#可以查看创建表的明细
BEGIN;
--
-- Create model Post
--
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, "crated" 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_slug_b95473f2" ON "blog_post" ("slug");
CREATE INDEX "blog_post_author_id_dd7a8485" ON "blog_post" ("author_id");
COMMIT; python manager migrate #同步数据库,应用已经存在的数据迁移

Applying blog.0001_initial... OK  #成功

创建超级管理员

python manage.py createsuperuser
Username (leave blank to use 'root'): admin
Email address:
Password:
Password (again):
Error: Your passwords didn't match.
Password:
Password (again):
Superuser created successfully.

成功后可以通过 127.0.0.1:8000/admin 来登陆管理界面

《Django By Example》第一章 学习笔记

这是看到的界面 使用刚刚的用户名密码可以进入该应用

《Django By Example》第一章 学习笔记

在admin.py里可以注册管理你的应用

#coding:utf-8
from django.contrib import admin
from .models import Post admin.site.register(Post)

《Django By Example》第一章 学习笔记

可以看到多了BLOG应用下的posts了,点进去即可以管理了

定制models的展示形式

from django.contrib import admin
from .models import Post class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'author', 'publish',
'status')
admin.site.register(Post, PostAdmin)

  有更多 选项定制管理模型

class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'author', 'publish',
'status') #显示列表
list_filter = ('status', 'created', 'publish', 'author') #过滤列表
search_fields = ('title', 'body')  #搜索栏
prepopulated_fields = {'slug': ('title',)} #
raw_id_fields = ('author',) #接受id输入
date_hierarchy = 'publish' #有个可以通过时间层快速导航的栏,该栏通过定义date_hierarchy属性出现
ordering = ['status', 'publish']  排序方式

《Django By Example》第一章 学习笔记

这是修改后的显示页面

查询集(QuerySet)什么时候会执行

只要你喜欢,你可以连接许多的过滤给查询集(QuerySet)而且不会立马在数据库中执行直到这个查询集(QuerySet)被执行。查询集(QuerySet)只有在以下情况中才会执行:

* 在你第一次迭代它们的时候
* 当你对它们的实例进行切片:例如`Post.objects.all()[:3]`
* 当你对它们进行了打包或缓存
* 当你对它们调用了`repr()`或`len()`方法
* 当你明确的对它们调用了`list()`方法
* 当你在一个声明中测试它,例如*bool()*, or, and, or if