想要彻底的搞清楚Django框架的所有使用逻辑和方法,谈何容易,建议自己常写写文档会加深记忆,捋清思路:
{数据和逻辑能够彻底地分开}
视图负责处理一些主观逻辑,然后返回响应结果。在当代 Web 应用中,主观逻辑经常牵涉到与数据库的交互。 数据库驱动网站 在后台连接数据库服务器,从中取出一些数据,然后在 Web 页面用漂亮的格式展示这些数据。 这个网站也可能会向访问者提供修改数据库数据的方法。许多复杂的网站都提供了以上两个功能的某种结合。 例如 Amazon.com 就是一个数据库驱动站点的良好范例。 本质上,每个产品页面都是数据库中数据以 HTML格式进行的展现,而当你发表客户评论时,该评论被插入评论数据库中。由于先天具备 Python 简单而强大的数据库查询执行方法,Django 非常适合开发数据库驱动网站。
Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。Django 为这些数据库提供了统一的调用API。
DRY和SHY都是为了达到松耦合,为了提高程序的可维护性。其中Dry强调了共性,提取整合共性,比如类的复用和继承。Shy则强调了个性,避免一个类或者模块与其他产生复杂的交叉关系。 “Don't Repeat Yourself”
在 Django 中使用 MySQL
MySQL 是 Web 应用中最常用的数据库。[MySQL 教程]
使用python3自带的数据库SQLite。教程见[Django Documentation - Writing your first Django app, part 1 - Database setup]
首先下载并安装MySQL
django要求MySQL4.0或更高的版本。 3.X 版本不支持嵌套子查询和一些其它相当标准的SQL语句。
安装参考:[Mysql数据库安装及配置]
下载和安装mysqldb或者python-mysql
参考[python操作mysql时mysqldb和pymysql的安装和使用]
数据库配置
初始配置
我们需要告诉Django使用什么数据库以及如何连接数据库。
假定你已经完成了数据库服务器的安装和激活,并且已经在其中创建了数据库(例如,用 CREATE DATABASE books;)。 如果你使用SQLite,不需要这步安装,因为SQLite使用文件系统上的独立文件来存储数据。
数据库配置也是在Django的配置文件里,缺省 是 settings.py 。
<span style="color:#33CC00;"><strong><span style="background-color:rgb(255,255,255)">DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'books', #这里不要用绝对路径!
'USER': 'pipi',
'PASSWORD': '********',
'HOST': '',
'PORT': '',
}
}</span></strong></span>:
1. 配置文件说明:
DATABASE_USER 告诉 Django 用哪个用户连接数据库。 例如: 如果用SQLite,空白即可。
DATABASE_PASSWORD 告诉Django连接用户的密码。 SQLite 用空密码即可。
DATABASE_HOST 告诉 Django 连接哪一台主机的数据库服务器。 如果数据库与 Django 安装于同一台计算机(即本机),可将此项保留空白。如果你使用SQLite,此项留空。此处的 MySQL 是一个特例。
2. 如果使用的是 MySQL 且该项设置值由斜杠('/' )开头,MySQL 将通过 Unix socket 来连接指定的套接字,例如:DATABASE_HOST = '/var/run/mysql'
3. 上面包含数据库名称和用户的信息,它们与MySQL中对应数据库和用户的设置相同。Django根据这一设置,与MySQL中相应的数据库和用户连接起来。
4. 当你编辑 settings.py 时,将 TIME_ZONE 修改为你所在的时区。默认值是美国中央时区(芝加哥)。
配置纲要
DATABASE_ENGINE 告诉Django使用哪个数据库引擎。 如果你在 Django 中使用数据库,DATABASE_ENGINE 必须是 Table 5-1 中所列出的值。
设置 | 数据库 | 所需适配器 |
---|---|---|
`` postgresql`` | PostgreSQL | psycopg 1.x版,http://www.djangoproject.com/r/python-pgsql/1/。 |
postgresql_psycopg2 | PostgreSQL | psycopg 2.x版,http://www.djangoproject.com/r/python-pgsql/。 |
mysql | MySQL | MySQLdb ,http://www.djangoproject.com/r/python-mysql/. |
sqlite3 | SQLite | 如果使用Python 2.5+则不需要适配器。 否则就使用 pysqlite ,http://www.djangoproject.com/r/python-sqlite/。 |
oracle | Oracle | cx_Oracle ,http://www.djangoproject.com/r/python-oracle/. |
要注意的是无论选择使用哪个数据库服务器,都必须下载和安装对应的数据库适配器。
配置数据库连接MySQL
安装对应的mysql数据库插件。
MySQLdb还不支持python3,所以用的是替代品PyMySQL。
1. pip安装pymysql适配器
pip install pymysql
2. 下载pyMysql安装包并安装:
python setup.py install
Note:
1.系统是ubuntu14.04,安装pymysql非常简单:$ sudo pip3 install PyMySQL
2. 安装完成后可能要重启pycharm, import pymysql才不会出错。
3. pymysql用法参考[Example]
在上面建好的django项目的init.py中加入
-
import pymysql
-
pymysql.install_as_MySQLdb()
测试配置
在`` VoteSite`` 项目目录下执行上章所提到的`` python manage.py shell`` 来进行测试。
输入下面这些命令来测试你的数据库配置:
<span style="color:#33CC00;"><strong>from django.db import connection
cursor = connection.cursor()</strong></span>
如果没有显示什么错误信息,那么你的数据库配置是正确的。
http://blog.csdn.net/pipisorry/article/details/45061579
创建app
确认数据库连接正常工作了,让我们来创建一个 Django app-一个包含模型,视图和Django代码,并且形式为独立Python包的完整Django应用。
project 和app 之间的区别
一个project包含很多个Django app以及对它们的配置。
技术上,project的作用是提供配置文件,比方说哪里定义数据库连接信息, 安装的app列表, TEMPLATE_DIRS ,等等。
一个app是一套Django功能的集合,通常包括模型和视图,按Python的包结构的方式存在。例如,Django本身内建有一些app,例如注释系统和自动管理界面。 app的一个关键点是它们是很容易移植到其他project和被多个project复用。
对于如何架构Django代码并没有快速成套的规则。 如果你只是建造一个简单的Web站点,那么可能你只需要一个app就可以了; 但如果是一个包含许多不相关的模块的复杂的网站,例如电子商务和社区之类的站点,那么你可能需要把这些模块划分成不同的app,以便以后复用。
你可以不用创建app,这一点应经被我们之前编写的视图函数的例子证明了 。 在那些例子中,我们只是简单的创建了一个称为views.py的文件,编写了一些函数并在URLconf中设置了各个函数的映射。但是,系统对app有一个约定: 如果你使用了Django的数据库层(模型),你 必须创建一个Django app。 模型必须存放在apps中。
创建app
在`` VoteSite`` 项目文件下输入下面的命令来创建`` books`` app:
<span style="color:#33CC00;"><strong>python manage.py startapp books</strong></span>
这个命令并没有输出什么,它只在 mysite 的目录里创建了一个books 目录。 让我们来看看这个目录的内容:
books/
__init__.py
models.py
tests.py
views.py
这个目录包含了这个app的模型和视图。它们都是空的,除了 models.py 里有一个 import。
定义模型
Django模型是用Python代码形式表述的数据在数据库中的定义。 对数据层来说它等同于 CREATE TABLE 语句,只不过执行的是Python代码而不是 SQL,而且还包含了比数据库字段定义更多的含义。 Django用模型在后台执行SQL代码并把结果用Python的数据结构来描述。Django也使用模型来呈现SQL无法处理的高级概念。
用Python 和 SQL来定义数据模型的原因:
自省(运行时自动识别数据库)会导致过载和有数据完整性问题。 为了提供方便的数据访问API, Django需要以 某种方式 知道数据库层内部信息,有两种实现方式。第一种方式是用Python明确地定义数据模型,第二种方式是通过自省来自动侦测识别数据模型。第二种方式看起来更清晰,因为数据表信息只存放在一个地方-数据库里,但是会带来一些问题。 首先,运行时扫描数据库会带来严重的系统过载。 第二,某些数据库,尤其是老版本的MySQL,并未完整存储那些精确的自省元数据。
保持用Python的方式思考会避免你的大脑在不同领域来回切换。 尽可能的保持在单一的编程环境/思想状态下可以帮助你提高生产率。把数据模型用代码的方式表述来让你可以容易对它们进行版本控制。 这样,你可以很容易了解数据层 的变动情况。
SQL只能描述特定类型的数据字段。 例如,大多数数据库都没有专用的字段类型来描述Email地址、URL。 而用Django的模型可以做到这一点。 好处就是高级的数据类型带来更高的效率和更好的代码复用。
SQL还有在不同数据库平台的兼容性问题。 发布Web应用的时候,使用Python模块描述数据库结构信息可以避免为MySQL, PostgreSQL, and SQLite编写不同的CREATETABLE。
当然,这个方法也有一个缺点,就是Python代码和数据库表的同步问题。 如果你修改了一个Django模型, 你要自己来修改数据库来保证和模型同步。 我们将在稍后讲解解决这个问题的几种策略。
最后,Django提供了实用工具来从现有的数据库表中自动扫描生成模型。 这对已有的数据库来说是非常快捷有用的。
定义模型
基本的 书籍/作者/出版商 数据库结构。假定下面的这些概念、字段和关系:
-
一个作者有姓,有名及email地址。
-
出版商有名称,地址,所在城市、省,国家,网站。
-
书籍有书名和出版日期。 它有一个或多个作者(和作者是多对多的关联关系[many-to-many]);只有一个出版商(和出版商是一对多的关联关系[one-to-many],也被称作外键[foreign key])
打开由`` startapp`` 命令创建的models.py 并输入:
<span style="color:#33CC00;"><strong>from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()</strong></span>
注释:
1. 它的父类 Model 包含了所有必要的和数据库交互的方法,并提供了一个简洁漂亮的定义数据库字段的语法。
2. 每个模型相当于单个数据库表,每个属性也是这个表中的一个字段。 属性名就是字段名,它的类型(例如 CharField )相当于数据库的字段类型 (例如 varchar )。例如, Publisher 模块等同于下面这张表(用PostgreSQL的CREATETABLE 语法描述):
<span style="color:#C0C0C0;">CREATE TABLE "books_publisher" (
"id" serial NOT NULL PRIMARY KEY,
"name" varchar(30) NOT NULL,
"address" varchar(50) NOT NULL,
"city" varchar(60) NOT NULL,
"state_province" varchar(30) NOT NULL,
"country" varchar(50) NOT NULL,
"website" varchar(200) NOT NULL
);</span>
Django 可以自动生成这些 CREATETABLE 语句。
3. “每个数据库表对应一个类”这条规则的例外情况是多对多关系。 在我们的范例模型中, Book 有一个 多对多字段 叫做authors 。 该字段表明一本书籍有一个或多个作者,但Book 数据库表却并没有 authors 字段。相反,Django创建了一个额外的表(多对多连接表)来处理书籍和作者之间的映射关系。
4. 我们并没有显式地为这些模型定义任何主键。 除非你单独指明,否则Django会自动为每个模型生成一个自增长的整数主键字段每个Django模型都要求有单独的主键id
{在数据库中创建这些表}
将 books app 添加到配置文件的已安装应用列表中
settings.py > INSTALLED_APPS 设置。 INSTALLED_APPS 告诉 Django 项目哪些 app 处于激活状态。
添加`` ‘VoteSite.books’`` 到`` INSTALLED_APPS`` 的末尾
<span style="background-color:rgb(255,255,255)">INSTALLED_APPS</span> = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
<strong><span style="color:#33CC00;">'books',</span></strong>
#如果当前路径就在VoteSite中,就可以去掉前缀VoteSite.
):就像我们在上一章设置TEMPLATE_DIRS所提到的逗号,同样在INSTALLED_APPS的末尾也需添加一个逗号,因为这是个单元素的元组。
将这些更改存储为迁移文件
告诉Django,你已经对模型做了一些更改(在这个例子中,你新建了一些模型)。
$ python manage.py makemigrations books
注释:
1. Django通过迁移文件来保存你对模型的改动(这些改动以后会使数据库表也发生相应的变化)-迁移文件在硬盘上真实地存在着。你能够阅读这些迁移文件;比如这次改动所生成的迁移文件books/migrations/0001_initial.py。但当每次Django生成迁移文件的时候,你不用都去读它们。它们只是被设计成人类可以进行编辑的格式,以便在Django改动数据库表之前,你可以轻微地手动修改Django的一些具体行为。
2. 有一个命令可以运行这些迁移文件,并且自动更新你的数据库表-它叫做migrate,一会儿会用到。
看一下迁移行为将会执行哪些SQL语句
sqlmigrate命令需要输入迁移文件的名字作为参数,它会返回迁移行为所需执行的SQL语句:
$ python manage.py sqlmigrate books 0001
输出:
BEGIN;
CREATE TABLE ...
CREATE INDEX ...
ALTER TABLE ...
ADD CONSTRAINT ...
COMMIT;
注释:
1. 输出的具体内容会因为你使用的数据库的不同而不同。
2. 数据表的名称是自动生成的。这个名称由app的名字和模型名字的小写字母组合而成。(你可以重写此行为。)
3. 主键(IDs)是自动添加的。(你也可以重写此行为。)
4. 按照惯例,Django会在外键的字段名后面添加"_id"。(是的,你依然可以重写此行为)
5. 外键关系由FOREIGN KEY语句显示声明。不用在意DEFERRABLE部分;它只是告诉PostgreSQL直到事务的最后再执行外键关联。
6. 这些SQL语句是针对你所使用的数据库量身定做的,会为你自动处理某些数据库所特有的字段。例如,auto_increment(MySQL),serial(PostgreSQL),或者integerprimarykeyautoincrement(SQLite)。在处理字段名的引号时也是如此。例如,有时使用双引号,有时使用单引号。
7. sqlmigrate命令并不会真正改变你的数据库-它只是把Django要做的事打印在屏幕上,来让你知道。这个语句对于检查Django将要进行的数据库操作是非常有用的。或者你拥有数据库管理员,并且想要获得这些SQL脚本来自己执行操作,这个语句也十分有用。
8. 如果你感兴趣的话,也可以运行pythonmanage.pycheck命令;它能在你没有执行迁移或者没有接触到数据库时,检查你的项目中是否存在问题。
在数据库中创建模型所对应的数据表
运行migrate命令:
E:\mine\python_workspace\VoteSite>python manage.py migrate
Operations to perform:
Apply all migrations: books, admin, sessions, auth, contenttypes
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying books.0001_initial... OK
Applying sessions.0001_initial... OK
注释:
1. migrate是干什么的呢,简单来说就是它可以让我们在修改Model后可以在不影响现有数据的前提下重建表结构。
2. migrate命令会找出所有还没有被应用的迁移文件(Django使用数据库中的一个叫做django_migrations的特殊的表来追踪哪些迁移文件已经被应用过了),并且运行他们来更新你的数据库-本质上来讲,就是使数据库表和改动后的模型进行同步。
3. 迁移功能是非常有用的。可以让你在开发过程中,使用现有的模型一段时间之后还能对其进行修改。并且不用删除现有数据库或者数据库表,也不用重新生成。-它致力于在程序运行过程中,不丢失数据的情况下升级你的数据库。
4.A New Field Means a New Migration
5. django <1.7使用第三方south做数据库迁移,>=1.7将south整合到django里,因此自带数据库迁移功能。这里是>=1.7的数据库迁移。django>=1.7数据库迁移只有三个命令
migrate,用来迁移数据库。用法:migrate app
makemigrations,用来检测数据库变更和生成数据库迁移文件。用法:makemigratioins app
sqlmigrate,用来把数据库迁移文件转换成数据库语言(displays the SQL statements for a migratioin.)用法:sqlmigrate app migration,比如makemigrations生成了0001_initial.py,就用sqlmigrate app 0001_intial,这里0001_initial就是migration参数。
一般如果某次migration使用sqlmigrate没有提示错误,那么在migrate时就能成功。如果migrate失败了,可以用sqlmigrate调试。
记住这三步来实现模型的变更:
- 修改你的模型(在models.py中)。
- 运行python manage.py makemigrations命令为这些改动创建迁移文件。
- 运行python manage.py migrate命令将这些改动应用到数据库中。
Django模型(字段及命令行和admin上进行数据库操作)
views.py中进行数据库操作
接下来我们在 HelloWorld 目录中添加 testdb.py 文件,并修改urls.py:
from django.conf.urls import *
from HelloWorld.view import hello
from HelloWorld.testdb import testdb
urlpatterns = patterns("",
('^hello/$', hello),
('^testdb/$', testdb),
)
添加数据
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from TestModel.models import Test
# 数据库操作
def testdb(request):
test1 = Test(name='pipi')
test1.save()
return HttpResponse("<p>数据添加成功!</p>")
访问http://192.168.45.3:8000/testdb/ 就可以看到数据添加成功的提示。
获取数据
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from TestModel.models import Test
# 数据库操作
def testdb(request):
# 初始化
response = ""
response1 = ""
list = Test.objects.all()
response2 = Test.objects.filter(id=1)
response3 = Test.objects.get(id=1)
Test.objects.order_by('name')[0:2]
Test.objects.order_by("id")
Test.objects.filter(name="w3cschool.cc").order_by("id")
# 输出所有数据
for var in list:
response1 += var.name + " "
response = response1
return HttpResponse("<p>" + response + "</p>")
view.py中使用 Django 数据库 API视图调用数据库数据
from django.shortcuts import render_to_response<span style="color:#66d9ef;font-style:italic">
def </span><span style="color:#a6e22e;">news</span>(<span style="color:#fd971f;font-style:italic">request</span>)<span style="color:#f92672;">:
</span><span style="color:#f92672;"> </span><span style="color:#75715e;"># newss = News.objects.all()
</span><span style="color:#75715e;"> </span>newss <span style="color:#f92672;">= </span>News.objects.order_by(<span style="color:#e6db74;">'time_stamp'</span>)
context <span style="color:#f92672;">= </span>{<span style="color:#e6db74;">'newss'</span><span style="color:#f92672;">:</span>newss}
<span style="color:#66d9ef;font-style:italic">return </span>render_to_response(<span style="color:#e6db74;">'bigdata/news.html'</span>, context)
Note:小技巧: return render_to_response('bigdata/team-pi.html', locals())
locals()就是代表函数中所有变量的字典,直接代替context.
Django执行逻辑MVT/MVC:(客户端看到的是模板内容HTML网页呈现)
ORM:概述,O:对象、R:关系,M:映射。
- 任务:根据对象的类型生成表结构
- 将对象、列表的操作转化为sql语句
- 将sql语句查询到的记过,转换为对象挥着对象
- 优点:极大的减轻了开发人员的工作(不管是什么数据库都是相同api
- 不需要因为数据库的不同而,使用不同的API,或者code)