Django系列教程:七、模型(二)
注明:python版本为3.3.1、Django版本为1.5.1,操作系统为Windows7,其他版本有一些不同的地方读者可以自行探讨。
上一章我们讲到了模型的一些基本概念以及postgreSQL数据库的简单配置,接下来我们就通过一个简单的例子来讲述一下在Django模型中是如何进行CURD操作的。
所谓CURD其实就是数据的创建Create、更新Update、读取Read和删除Delete功能,要实现这些功能,以往常常需要使用SQL语句去实现,比如SELECT语句、UPDATE语句等等,但由于不同的数据库之间存在着差异,使用这些SQL语句时就会出现这样那样的问题,所以为了解决这个问题,Django中将这几类操作进行了统一和规范,形成了自己独有的一套体系,使得程序人员不用怎么熟悉SQL语句也能创建统一规范的数据库或数据表格,下面我们就一步一步来看看Django是如何实现的。
打开上一节我们创建的books这个app下面的models.py文件,将其代码更改为如下:(这个例子源于DjangoBook的书中,因为比较简单所以直接拿过来用,其它的一些配置请按上一章讲到的配置即可)
# Create your models here. 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()
上面的代码的意思其实就是create了三个表,一个Publisher表,一个Author表,一个Book表,每一次创建表格实际上就是执行了一个类里面的代码,就那class Book来说:
models.Model的意思就是前面继承后面,后面的title、authors、publisher、publication_date则是你表里面的字段名称,其后的CharField、ManyToMany、ForeignKey、DateField则分别是字段的类型,括号里放的就是其参数。简单吧,又比如第一个class Publisher其效果实际等价于下面的SQL代码。
CREATE TABLE "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 );
当然,我们如果怕上面的模型有错误,那么不妨来验证一下,可以用下面的验证代码来验证。
python manage.py validate
出现下面的0 error则表示你创建的模型没有问题。
好了,模型的创建已经完成了,下面就是将这几段代码执行,只有执行后再数据库中才会出现相应的表,否则就一直是一个死的文本而已。
在django中一般使用这个命令来执行。
python manage.py syncdb
其执行效果如下:
打开你的数据库,你便可以看到下面三个表。
自动生成的表名是app名称( books )和模型的小写名称 ( publisher , book , author )的组合。当然部分地方因为我提前创建过了,有可能不一样,不过大家可以百度相关函数查询其具体的用法。
其中还有一个命令是将models.py里面的代码转化为SQL代码,如:
其运行后便会返回出一段SQL的代码,但是还没有执行,只是相当于翻译了一下。得到的代码如下:
1 BEGIN; 2 CREATE TABLE "books_publisher" ( 3 "id" serial NOT NULL PRIMARY KEY, 4 "name" varchar(30) NOT NULL, 5 "address" varchar(50) NOT NULL, 6 "city" varchar(60) NOT NULL, 7 "state_province" varchar(30) NOT NULL, 8 "country" varchar(50) NOT NULL, 9 "website" varchar(200) NOT NULL 10 ) 11 ; 12 CREATE TABLE "books_author" ( 13 "id" serial NOT NULL PRIMARY KEY, 14 "first_name" varchar(30) NOT NULL, 15 "last_name" varchar(40) NOT NULL, 16 "email" varchar(75) NOT NULL 17 ) 18 ; 19 CREATE TABLE "books_book_authors" ( 20 "id" serial NOT NULL PRIMARY KEY, 21 "book_id" integer NOT NULL, 22 "author_id" integer NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INI 23 TIALLY DEFERRED, 24 UNIQUE ("book_id", "author_id") 25 ) 26 ; 27 CREATE TABLE "books_book" ( 28 "id" serial NOT NULL PRIMARY KEY, 29 "title" varchar(100) NOT NULL, 30 "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id") DEFERRAB 31 LE INITIALLY DEFERRED, 32 "publication_date" date NOT NULL 33 ) 34 ; 35 ALTER TABLE "books_book_authors" ADD CONSTRAINT "book_id_refs_id_0a3634f3" FOREI 36 GN KEY ("book_id") REFERENCES "books_book" ("id") DEFERRABLE INITIALLY DEFERRED; 37 38 CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id"); 39 40 COMMIT;
sqlall 命令并没有在数据库中真正创建数据表,只是把SQL语句段打印出来,这样你可以看到Django究竟会做些什么。
好了,数据表创建成功了,那么下面我们来进行一些简单的数据操作。
这里我们暂时在python manage.py shell执行相应的代码来说明这些问题,到以后便可以将这些代码写到相应的文件中去处理了。
输入下面的代码:
>>> from books.models import Publisher >>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue', ... city='Berkeley', state_province='CA', country='U.S.A.', ... website='http://www.apress.com/') >>> p1.save() >>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.', ... city='Cambridge', state_province='MA', country='U.S.A.', ... website='http://www.oreilly.com/') >>> p2.save()
上面的代码的意思相信不难理解,其实就是给表格中的字段赋值,而p1.save()就是将数据保存到数据库中。
这时你再查询你的数据库看看是不是多了一条数据了。
我只输入了第一段代码p1,所以只有一条数据了,大家可以多输入几条数据试试看,其它数据表的赋值也是一样。
再紧接着上面的代码输入:
Publisher.objects.all()
这时你将得到Publisher中创建的对象,如我的是:
[<Publisher: Apress>]
当然,如果你按照上面的操作可能得到的是[<Publisher: Apress>,<Publisher:O'Reillys>],这是因为你的Publisher中有两个对象了。
不过其中要注意的一个问题就是你可能出不来上面的[<Publisher: Apress>],而只是显示:[<Publisher: Publisher object>],这该怎么办呢?
这时只要在models.py文件中的class Publisher类中加入下面一行代码即可。
1 class Publisher(models.Model): 2 name = models.CharField(max_length=30) 3 address = models.CharField(max_length=50) 4 city = models.CharField(max_length=60) 5 state_province = models.CharField(max_length=30) 6 country = models.CharField(max_length=50) 7 website = models.URLField() 8 def __str__(self): 9 return self.name
注意到什么变化没有,即添加了第8和第9行两行代码。很多教材中因为版本比较旧,其中说道的添加__unicode__()这个方法其实是不对的,在python3.x中已经改变了,诸位可以参见我前面的一篇文章。
好了,至于数据的查询、更新、插入、删除等操作与上面的大都类似,应该可以举一反三,在学习的过程中还是要自己多动手操作,这里我就不再讲解了,问题应该不大。
最近毕设忙的不可开交,导致更新没及时很抱歉,希望我能继续坚持下去,其实有人说道我的这些并不足以当教程,也就是个学习笔记,我对他提得建议很赞同,但是已经写了这么久了,就懒得去改了,以后等回过头来不断修复和完善吧,不过或多或少对自己和某些人还是有帮助的,谢谢了。下一章我们讲新内容。
本人既是python的初学者也是Django的初学者,写这一系列教程的目的就是为了加深自己的理解,希望大家多多包涵和指教,有什么问题请留言,谢谢。