您的位置:首页 > 数据库

第五章:数据库交换开发篇

2011-11-01 16:29 253 查看
一、简要描述:

Web应用中,很多业务逻辑经常牵涉到与数据库的交互。数据库驱动网站在后台连接数据库服务器,从中取出一些数据,然后在Web页面用漂亮的格式展示这些数据。或者,站点也提供让访问者自行填充数据库的功能。

只有使用

1、简单数据查询

fromdjango.shortcutsimportrender_to_response
importMySQLdb

defbook_list(request):
db=MySQLdb.connect(user='me',db='mydb',passwd='secret',host='localhost')
cursor=db.cursor()
cursor.execute('SELECTnameFROMbooksORDERBYname')
names=[row[0]forrowincursor.fetchall()]
db.close()
returnrender_to_response('book_list.html',{'names':names})


这种方法可以用,但是不是最理想的方法,在Web开放中是有很多数据操作类,如果每一个类都写数据连接,关闭那太繁琐了。

我们希望不重复同样的代码:创建数据库连接、创建数据库游标、执行某个语句、然后关闭数据库。

下介绍的内容中就可以解决这个问题,也是Django框架对Web开放的很好的支持。

MTV开发模式

1、MVC:了解MTV之前我们还是先复习一下MVC吧。

Django紧紧地遵循这种MVC模式,可以称得上是一种MVC框架

M,数据存取部分,由django数据库层处理,本章要讲述的内容。

V,选择显示哪些数据要及怎样显示的部分,由视图和模板处理。

C,根据用户输入委派视图的部分,由Django框架通过按照URLconf设置,对给定URL调用合适的python函数来自行处理。

2、MTV:那到底什么是MTV呢?

模型(Model)、模板(Template)和视图(Views),Django也被称为MTV框架。

M代表模型(Model),即数据存取层。该层处理与数据相关的所有事务:如何存取、如何确认有效性、包含哪些行为以及数据之间的关系等。

T代表模板(Template),即表现层。该层处理与表现相关的决定:如何在页面或其他类型文档中进行显示。

V代表视图(View),即业务逻辑层。该层包含存取模型及调取恰当模板的相关逻辑。你可以把它看作模型与模板之间的桥梁。

数据库配置

 1、缺省匹配

  打开项目Mysite在根目录下可以看到“settings.py”文件,找到DATABASES配置如下:

DATABASES={
'default':{
'ENGINE':'',#Add'postgresql_psycopg2','postgresql','mysql','sqlite3'or'oracle'.
'NAME':'',#Orpathtodatabasefileifusingsqlite3.
'USER':'',#Notusedwithsqlite3.
'PASSWORD':'',#Notusedwithsqlite3.
'HOST':'',#Settoemptystringforlocalhost.Notusedwithsqlite3.
'PORT':'',#Settoemptystringfordefault.Notusedwithsqlite3.
}
}


  代码描述:

DATABASE_ENGINE数据库引擎设置

DATABASE_NAME将数据库名称告知Django。如果使用SQLite,请对数据库文件指定完整的文件系统路径。(例如'/home/django/mydata.db')。

DATABASE_USER告诉Django用哪个用户连接数据库。如果用SQLite,空白即可。

DATABASE_PASSWORD告诉Django连接用户的密码。SQLite用空密码即可。

DATABASE_HOST告诉Django连接哪一台主机的数据库服务器。如果数据库与Django安装于同一台计算机(即本机),可将此项保留空白。使用SQLite,也可保留空白。

  2、数据库引擎设置

DATABASE_ENGINE告诉Django使用哪个数据库引擎

数据库引擎设置
设置数据库适配器

postgresqlPostgreSQLpsycopg版本1.x,
  http://www.djangoproject.com/r/python-pgsql/1/.

  postgresql_psycopg2PostgreSQLpsycopg版本2.x,
  http://www.djangoproject.com/r/python-pgsql/.

  mysqlMySQLMySQLdb,
  http://www.djangoproject.com/r/python-mysql/.
  sqlite3SQLitePython2.5+内建。其他,pysqlite,
  http://www.djangoproject.com/r/python-sqlite/.

  ado_mssqlSQLServeradodbapi版本2.0.1+,MicrosoftSQLServer
  http://www.djangoproject.com/r/python-ado/.

  oracleOraclecx_Oracle,
  http://www.djangoproject.com/r/python-oracle/.

3、测试数据库配置

启动了一个Python交互界面:运行pythonmanage.pyshell命令

输入下面这些命令来测试你的数据库配置:

>>>fromdjango.dbimportconnection
>>>cursor=connection.cursor()


如果没有显示什么错误信息,那么你的数据库配置是正确的.

如果显示错误则配置数据库失败,检查错误代码,常见错误:

错误信息:YouhaventsettheDATABASE_ENGINEsettingyet.

解决方案:设置正确的DATABASE_ENGINE配置

错误信息:EnvironmentvariableDJANGO_SETTINGS_MODULEisundefined.

解决方案:运行命令行pythonmanage.pyshell而不是python.

错误信息:Errorloading_____module:Nomodulenamed_____.

解决方案:你没有安装相关的数据库适配器(例如,psycopg或MySQLdb).

错误信息:_____isntanavailabledatabasebackend.

解决方案:设置正确的DATABASE_ENGINE配置也许是拼写错误?

错误信息:database_____doesnotexist

解决方案:设置DATABASE_NAME配置到一个已有的数据库,或者使用CREATEDATABASE语句

创建数据库。

错误信息:role_____doesnotexist

解决方案:修改DATABASE_USER配置到一个有效用户

错误信息:couldnotconnecttoserver

解决方案:确认DATABASE_HOST和DATABASE_PORT设置是正确的,并确认服务器是在运行

的。

第一个数据交换应用程序

1、创建项目

转到mysite项目目录,执行命令创建books目录

pythonmanage.pystartappbooks


查看books文件目录中的文件:

books/
__init__.py
models.py
views.py


2、定义数据模型

  打开models.py并输入下面的内容:

  

#-*-coding:utf-8-*-
fromdjango.dbimportmodels
fromdjango.contribimportadmin

classPublisher(models.Model):
name=models.CharField(max_length=30,blank=True)
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()
def__unicode__(self):
returnself.name
#默认排序设置
#classMeta:
#ordering=["name"]

#Admin声明标志了该类有一个管理界面'''
classAdmin:
pass

classAuthor(models.Model):
salutation=models.CharField(max_length=10)
first_name=models.CharField(max_length=30)
last_name=models.CharField(max_length=40)
email=models.EmailField(max_length=30)
#headshot=models.ImageField(upload_to='/tmp')
def__unicode__(self):
return'%s%s'%(self.first_name,self.last_name)
#Admin声明标志了该类有一个管理界面'''
classAdmin:
pass

classBook(models.Model):
title=models.CharField(max_length=100)
authors=models.ManyToManyField(Author)
publisher=models.ForeignKey(Publisher)
publication_date=models.DateField()
num_page=models.IntegerField(blank=True,null=True)

def__unicode__(self):
return'Bookname:%s'%self.title


模型安装

再次编辑settings.py文件,找到INSTALLED_APPS设置,INSTALLED_APPS告诉Django项目哪些app处于激活状态,

缺省情况下如下所示:

INSTALLED_APPS=(
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
)


把INSTALLED_APPS设置中四个设置前面加#临时注释起来,

改缺省的MIDDLEWARE_CLASSES和TEMPLATE_CONTEXT_PROCESSORS设置,都注释起来。然后添加'mysite.books'到INSTALLED_APPS列表,现在看起来是这样:

MIDDLEWARE_CLASSES=(
#'django.middleware.common.CommonMiddleware',
#'django.contrib.sessions.middleware.SessionMiddleware',
#'django.contrib.auth.middleware.AuthenticationMiddleware',
#'django.middleware.doc.XViewMiddleware',
)

TEMPLATE_CONTEXT_PROCESSORS=()
#...

INSTALLED_APPS=(
#'django.contrib.auth',
#'django.contrib.contenttypes',
#'django.contrib.sessions',
#'django.contrib.sites',
'mysite.books',
)


校验模型的有效性:

pythonmanage.pyvalidate


0errorsfound消息:表示一切正常

否则就是错误,检查数据模型是否正确。

生成SQL语句:

pythonmanage.pysqlallbooks


运行命令的结果是这样的:

BEGIN;
CREATETABLE"books_publisher"(
"id"serialNOTNULLPRIMARYKEY,
"name"varchar(30)NOTNULL,
"address"varchar(50)NOTNULL,
"city"varchar(60)NOTNULL,
"state_province"varchar(30)NOTNULL,
"country"varchar(50)NOTNULL,
"website"varchar(200)NOTNULL
);
CREATETABLE"books_book"(
"id"serialNOTNULLPRIMARYKEY,
"title"varchar(100)NOTNULL,
"publisher_id"integerNOTNULLREFERENCES"books_publisher"("id"),
"publication_date"dateNOTNULL
);
CREATETABLE"books_author"(
"id"serialNOTNULLPRIMARYKEY,
"salutation"varchar(10)NOTNULL,
"first_name"varchar(30)NOTNULL,
"last_name"varchar(40)NOTNULL,
"email"varchar(75)NOTNULL,
"headshot"varchar(100)NOTNULL
);
CREATETABLE"books_book_authors"(
"id"serialNOTNULLPRIMARYKEY,
"book_id"integerNOTNULLREFERENCES"books_book"("id"),
"author_id"integerNOTNULLREFERENCES"books_author"("id"),
UNIQUE("book_id","author_id")
);
CREATEINDEXbooks_book_publisher_idON"books_book"("publisher_id");
COMMIT;


代码描述:

A、自动生成的表名是app名称(books)和模型的小写名称(publisher,book,author)的组合
B、Django会站点添加一个ID主键,是可以修改的。

C、按约定规则,Django添加的"_id"后缀到外键字段名。

D、外键是用REFERENCES语句明确定义的。

E、这些CREATETABLE语句会根据你的数据库而作调整,这样象数据库特定的一些字段例如:auto_increment(MySQL),serial(PostgreSQL),integerprimarykey(SQLite)可以自动处理。

同步数据库:

pythonmanage.pysyncdb


你将会看到这样的内容:

Creatingtablebooks_publisher
Creatingtablebooks_book
Creatingtablebooks_author
Installingindexforbooks.Bookmodel


重启服务器:

重启Web服务器

pythonmanage.pyrunserver


数据访问类

pythonmanage.pyshell进入

1、获取所以数据

>>>frombooks.modelsimportPublisher
>>>publisher_list=Publisher.objects.all()
>>>publisher_list
[<Publisher:lhj-588>,<Publisher:loker>]


2、插入数据

>>>frombooks.modelsimportPublisher
>>>p=Publisher(name='Apress',
...address='2855TelegraphAve.',
...city='Berkeley',
...state_province='CA',
...country='U.S.A.',
...website='http://www.apress.com/')
>>>p.save()


转换成SQL:

INSERTINTObook_publisher
(name,address,city,state_province,country,website)
VALUES
('Apress','2855TelegraphAve.','Berkeley','CA',
'U.S.A.','http://www.apress.com/');


3、修改数据

>>>frombooks.modelsimportPublisher
>>>p=Publisher(name='Apress'
,...address='2855TelegraphAve.'
,...city='Berkeley'
,...state_province='CA'
,...country='U.S.A.'
,...website='http://www.apress.com/')
>>>p.save()
>>>p.id
3
>>>p.name='apressPublishing'
>>>p.save()


后面执行的save()相当于下面的SQL语句:

UPDATEbook_publisherSET
name='ApressPublishing',
address='2855TelegraphAve.',
city='Berkeley',
state_province='CA',
country='U.S.A.',
website='http://www.apress.com'
WHEREid=52;


4、过滤数据filter()

>>>frombooks.modelsimportPublisher
>>>Publisher.objects.filter(country="U.S.A.",state_province="CA")
[<Publisher:ApressPublishing>]


相当于SQL语句:

SELECT
id,name,address,city,state_province,country,website
FROMbook_publisher
WHEREcountry='U.S.A.'ANDstate_province='CA';


5、获取单个对象

>>>frombooks.modelsimportPublisher
>>>Publisher.objects.get(name="ApressPublishing")

[<Publisher:ApressPublishing>]


如果查询出多个对象,则会导致抛出异常。

6、数据排序order_by

>>>frombooks.modelsimportPublisher
>>>Publisher.objects.order_by("name")

[<Publisher:ApressPublishing>,<Publisher:Addison-Wesley>,<Publisher:O'Reilly>]


相当于SQL:

SELECT
id,name,address,city,state_province,country,website
FROMbook_publisher
ORDERBYname;


可以指定逆向排序

Publisher.objects.order_by("-name")


7、限制返回的数据



>>>frombooks.modelsimportPublisher
>>>Publisher.objects.all()[0]
<Publisher:Addison-Wesley>
>>>Publisher.objects.all()[0:2]
[<Publisher:Addison-Wesley>,<Publisher:ApressPublishing>,<Publisher:Addison-Wesley>]



8、删除对象.delete()


>>>frombooks.modelsimportPublisher
>>>p=Publisher.objects.get(name="Addison-Wesley")
>>>p.delete()
>>>Publisher.objects.all()
[<Publisher:ApressPublishing>,<Publisher:O'Reilly>]
>>>publishers.delete()
>>>Publisher.objects.all()
[]


修改数据库表结构

你需要查看manage.pysqlall的执行结果

  同用步骤:

  A、修改数据模型

  B、同步数据库:执行pythonmanage.pysyncdb

  C、重启服务器:执行pythonmanage.pyrunserver

先修改在开发环境而不是发布服务器上修改

1、添加字段

在开发环境中执行下面的步骤:

把这个字段添加到你的模型中.

运行manage.pysqlall[yourapp]会看到模型的新的CREATETABLE语句。注意新的字段的列定义。

启动您的数据库交互shell(也就是psql或mysql,或者您也可以使用manage.pydbshell)。执行一个ALTERTABLE语句,添加您的新列

4.(可选)用manage.pyshell动ython交互式shell,并通过引入模型并选择表验证新的字段已被正确添加(比如,MyModel.objects.all()[:5])。

然后在发布服务器上执行下面的步骤:

启动你的数据库的交互式命令行;

执行ALTERTABLE语句,也就是在开发环境中第3步执行的语句;

添加字段到你的模型中。如果你在开发时使用了版本控制系统并checkin了你的修改,现在可以更新代码到发布服务器上了(例如,使用Subverison的话就是svnupdate)。

重启Web服务器以使代码修改生效

2、删除字段

从模型里删除一个字段可要比增加它简单多了。删除一个字段仅需要做如下操作:


从你的模型里删除这个字段,并重启Web服务器。

使用如下面所示的命令,从你的数据库中删掉该列:


3、删除Many-to-Many字段

因为many-to-many字段同普通字段有些不同,它的删除过程也不一样:


删除掉你的模型里的ManyToManyField,并且重启Web服务器。

使用如下面所示的命令,删除掉你数据库里的many-to-many表:


DROPTABLEbooks_books_publishers;

4、删除模型

完全删除一个模型就像删除一个字段一样简单。删除模型仅需要做如下步骤:


将此模型从你的models.py文件里删除,并且重启Web服务器。

使用如下的命令,将此表从你的数据库中删除:


DROPTABLEbooks_book;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐
章节导航