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;
View Code

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的初学者,写这一系列教程的目的就是为了加深自己的理解,希望大家多多包涵和指教,有什么问题请留言,谢谢。

posted @ 2013-06-02 22:56  倾杯天涯  阅读(881)  评论(0编辑  收藏  举报