Django学习总结之五模型

一、MTV开发模式

M:模型(model),数据存取层,处理与数据相关的所有事务。

T:模板(Template),表现层,处理与表现相关的决定。

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

二、数据库配置

打开setting.py 配置文件,找到:

 

DATABASE_ENGINE = ''
DATABASE_NAME = ''
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''

DATABASE_ENGINE:是数据库引擎,设置如下:

 

 

数据库引擎设置
设置 数据库 数据库引擎
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/

 

 









python2.5以上的版本中已经集成了sqlite,所以不需要安装数据库引擎。

DATABASE_NAME:数据库名称

如果使用sqlite,则指定将数据文件的完整地址。例如:DATABASE_NAME = '/home/django/mydata.db'

DATABASE_USER:使用哪个用户连接数据库,如果是sqlite,则留空。

DATABASE_PASSWORD:数据库密码,如果使用sqlite,留空。

DATABASE_HOST:连接哪一台主机的数据库服务器。如果数据库与django安装在同一台机器上留空。如果使用的是sqlite数据库,留空。

此处的 MySQL 是一个特例。 如果使用的是 MySQL 且该项设置值由斜杠( '/' )开头,MySQL 将通过 Unix socket 来连接指定的套接字,例如:

DATABASE_HOST = '/var/run/mysql'.

测试数据库配置:

进入mysite的目录,运行:python manage.py shell

 

>>> from django.db import connection
>>> cursor = connection.cursor()

如果没有出现错误信息提示,说明数据库配置成功!

 

常见的数据库配置错误信息如下:

 

错误信息 解决办法
You haven’t set the DATABASE_ENGINE setting yet. 不要以空字符串配置`` DATABASE_ENGINE`` 的值。
Environment variable DJANGO_SETTINGS_MODULE is undefined. 使用`` python manager.py shell`` 命令启动交互解释器,不要以`` python`` 命令直接启动交互解释器。
Error loading _____ module: No module named _____. 未安装合适的数据库适配器 (例如, psycopg 或 MySQLdb )。Django并不自带适配器,所以你得自己下载安装。
_____ isn’t an available database backend. 把DATABASE_ENGINE 配置成前面提到的合法的数据库引擎。 也许是拼写错误? 
database _____ does not exist 设置`` DATABASE_NAME`` 指向存在的数据库,或者先在数据库客户端中执行合适的`` CREATE DATABASE`` 语句创建数据库。
role _____ does not exist 设置`` DATABASE_USER`` 指向存在的用户,或者先在数据库客户端中执创建用户。
could not connect to server 查看DATABASE_HOST和DATABASE_PORT是否已正确配置,并确认数据库服务器是否已正常运行

三、第一个应用程序

 

1、project和project app的区别

一个project可以包含多个project app 以及对他们的配置,技术上讲,project是提供配置文件,project app是一套django功能的合集,通常包括模型和视图,按照python包结构的形式存在。系统对app有个约定,如果如果使用了django的数据库模型,就必须创建一个django app,模型必须放在app中。

创建方法:

在mysite目录下输入命令:

 

python manage.py startapp books

创建了一个app:books。此时mysite目录下生成了一个books的目录,文档结构为:

 

books/
    __init__.py
    models.py
    tests.py
    views.py

我们需要在python里定义模型,即实现类似于SQL语句的方式,但是如果你修改了模型,也必须修改数据库来保持和模型的同步。

2、第一个模型

我们假定一些概念和关系:

一个作者有姓,有名及email地址。
出版商有名称,地址,所在城市、省,国家,网站。
书籍有书名和出版日期。 它有一个或多个作者(和作者是多对多的关联关系[many-to-many]), 只有一个出版商(和出版商是一对多的关联关系[one-to-many],也被称作外键[foreign key])

下面来创建模型。打开books目录下的models.py 输入:

 

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()

注意:每个数据模型都是django.db.models.Model的子类,他的父类Model包含了所有必要的和数据库交互的方法。

 

每个模型相当于一个数据库表,每个属性代表表中的一个字段,属性名就是字段名,他的类型(如CharField)就相当于数据库的字段类型(例如varchar)。例如,Publisher模块就相当于以下这张表:

 

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
);

每个数据库表对应着一个类,例外情况是多对多的关系。例如,上表中的Book有个多对多的字段:authors,表明一本书有一个或者多个作者,但是在数据库表中却没有生产authors字段,而是创建了一个额外的表(多对多连接表)来处理书籍和作者之间多对多的关系。

 

Django还拥有描述URL和Email的字段类型:URLField、EmailField。最后,我们没有显式的为表定义主键,除非你单独指明,,否则django默认会为每一个数据表创建一个自增长的整数主键字段:id

3、模型的安装

1)激活模型

完成以上代码后,我们要在数据库中创建这些表,首先就需要在django项目中激活这些模型。将app添加到配置文件中已安装应用列表中即可实现。

编辑setting.py 文件,找到:INSTALLED_APPS.它是告诉django哪些app处于激活状态。缺省状态如下:

 

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)

先把前5个用#注释掉(这5个是经常用到的),同时,注释掉MIDDLEWARE_CLASSES的默认设置条目,因为这些条目是依赖于刚才我们刚在INSTALLED_APPS注释掉的apps。然后,添加`` ‘mysite.books’`` 到`` INSTALLED_APPS`` 的末尾,此时设置的内容应该这样:

 

 

MIDDLEWARE_CLASSES = (
    #'django.middleware.common.CommonMiddleware',
    #'django.contrib.sessions.middleware.SessionMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    #'django.contrib.auth.middleware.AuthenticationMiddleware',
    #'django.contrib.messages.middleware.MessageMiddleware',
)
INSTALLED_APPS = (
    #'django.contrib.auth',
    #'django.contrib.contenttypes',
    #'django.contrib.sessions',
    #'django.contrib.sites',
    #'django.contrib.messages',
    #'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
    'mysite.books',
)

2)验证模型的有效性

 

 

python manage.py validate

没有错误,说明模型正常有效。

 

3)生成CREATE TABLE语句

 

python manage.py sqlall books

其中,books是app的名称。

 

得到输出结果如下:

 

BEGIN;
CREATE TABLE "books_publisher" (
    "id" integer 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
)
;
CREATE TABLE "books_author" (
    "id" integer NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(40) NOT NULL,
    "email" varchar(75) NOT NULL
)
;
CREATE TABLE "books_book_authors" (
    "id" integer NOT NULL PRIMARY KEY,
    "book_id" integer NOT NULL,
    "author_id" integer NOT NULL REFERENCES "books_author" ("id"),
    UNIQUE ("book_id", "author_id")
)
;
CREATE TABLE "books_book" (
    "id" integer NOT NULL PRIMARY KEY,
    "title" varchar(100) NOT NULL,
    "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id"),
    "publication_date" date NOT NULL
)
;
CREATE INDEX "books_book_22dd9c39" ON "books_book" ("publisher_id");
COMMIT;

注意:

 

 

  • 自动生成的表名是app名称( books )和模型的小写名称 ( publisher , book , author )的组合。
  • 我们前面已经提到,Django为每个表格自动添加加了一个 id 主键,你可以重新设置它。
  • 按约定,Django添加 "_id" 后缀到外键字段名。 
  • 外键是用 REFERENCES 语句明确定义的。
  • 这些 CREATE TABLE 语句会根据你的数据库而作调整,这样象数据库特定的一些字段例如:(MySQL),auto_increment(PostgreSQL),serial(SQLite),都会自动生成。integer primary key 同样的,字段名称也是自动处理(例如单引号还好是双引号)。 

sqlall命令并没有在数据库中创建数据表,它只是将CREATE TABLE 命令打印出来,你可以将打印出来的命令复制到数据库客户端执行,但是django提供了更为简洁的提交SQL语句至数据库中的方法:syncdb命令。

 

 

python manage.py syncdb

执行完成后,你会看到输出:

 

 

Creating tables ...
Creating table books_publisher
Creating table books_author
Creating table books_book_authors
Creating table books_book
Installing custom SQL ...
Installing indexes ...
No fixtures found.

syncdb是同步你的模型到数据库的一个简洁的方法。他会根据INSTALLDE_APPS中设置的apps检查数据库,如果数据库不存在就会创建它。但是syncdb命令不会将模型的修改或者删除更新到数据库,如果你删除了一个模型,想把他提交到数据库,syncdb不会做任何操作。即,它只能创建数据库,不会对模型的修改或者删除更新。
4、基本数据访问

 

运行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()
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]

 

  • 首先,导入Publisher模型类, 通过这个类我们可以与包含 出版社 的数据表进行交互。
  • 接着,创建一个`` Publisher`` 类的实例并设置了字段`` name, address`` 等的值。
  • 调用该对象的 save() 方法,将对象保存到数据库中。 Django 会在后台执行一条 INSERT 语句。
  • 最后,使用`` Publisher.objects`` 属性从数据库取出出版商的信息,这个属性可以认为是包含出版商的记录集。 这个属性有许多方法, 这里先介绍调用`` Publisher.objects.all()`` 方法获取数据库中`` Publisher`` 类的所有对象。这个操作的幕后,Django执行了一条SQL `` SELECT`` 语句。

只有在调用save方法之后,才会把数据写入数据库。

 

如果想一步就写入到数据库中,可以使用下面这种方式:

 

>>> p1 = Publisher.objects.create(name='Apress',
...     address='2855 Telegraph Avenue',
...     city='Berkeley', state_province='CA', country='U.S.A.',
...     website='http://www.apress.com/')
>>> p2 = Publisher.objects.create(name="O'Reilly",
...     address='10 Fawcett St.', city='Cambridge',
...     state_province='MA', country='U.S.A.',
...     website='http://www.oreilly.com/')
>>> publisher_list = Publisher.objects.all()
>>> publisher_list

5、添加模块的字符表现

 

我们上一段的代码在输出publisher_list时并没有输有用的信息,要想解决这个问题,只需要为Publisher对象添加一个__unicode__()方法。__unicode__()方法将告诉python如何将对象以unicode的方式显示出来。为以上3个模型都添加__unicode__()方法:

 

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()

    def __unicode__(self):
	  return self.name

class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField()

    def __unicode__(self):
	  return u'%s %s' % (self.first_name, self.last_name)

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()

    def __unicode__(self):
      return self.title

 

Publisher返回的是出版社的名称,Book返回的是书名,Author返回的是first_name和last_name以空格连接后的字符串。我们可以使用__unicode__()方法进行任何处理来返回一个对象的字符串表示。以后要确保每一个模型都要有__unicode__()方法。

 

关闭shell打开的窗口,重新打开:python manage.py shell执行:

 

>>> from books.models import Publisher
>>> publish_list = Publisher.objects.all()
>>> publish_list
[<Publisher: Apress>, <Publisher: O'Reilly>]

这时,输出的是出版社的名称。

 

注意:在书写def __unicode__()的方法的时候,一定不要用tab键将def和上边的字段对齐,而是使用空格,一个空格一个空格的去对齐,否则运行:python manage.py shell总是报错!!

6、插入更新数据













 

posted @ 2013-05-13 23:16  javawebsoa  Views(214)  Comments(0Edit  收藏  举报