zoukankan      html  css  js  c++  java
  • Python框架之Django学习笔记(十)

      又是一周周末,如约学习Django框架。在上一次,介绍了MVC开发模式以及Django自己的MVT开发模式,此次,就从数据处理层Model谈起。

      数据库配置

      首先,我们需要做些初始配置;我们需要告诉Django使用什么数据库以及如何连接数据库。假定你已经完成了数据库服务器的安装和激活,并且已经在其中创建了数据库(例如,用 CREATE DATABASE语句)。 如果你使用SQLite,不需要这步安装,因为SQLite使用文件系统上的独立文件来存储数据。和前面章节提到的 TEMPLATE_DIRS 一样,数据库配置也是在Django的配置文件settings.py 里。 打开这个文件并查找数据库配置:  

    1 DATABASES = {
    2     'default': {
    3         'ENGINE': 'django.db.backends.sqlite3',
    4         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    5     }
    6 }

       原始配置如上所示,此为1.6.6版本的Django配置文件,恩,就是这样。如有不同也没关系。下面按照如下来配置数据库信息:  

     1 DATABASES = {
     2     'default': {
     3         'ENGINE': 'django.db.backends.mysql',   #数据库种类
     4         'NAME':'books',                         #数据名称
     5         'USER':'root',                                      
     6         'PASSWORD':'123456',
     7         'HOST':'127.0.0.1',
     8         'PORT':'3306',
     9     }
    10 }    

      配置保存之后,可以在命令行中进入工程目录下,如我的是“mysite”下,执行

    1 python manage.py shell

      进入命令行之后再进行测试。输入以下命令来进行测试: 

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

     如果没有显示什么错误信息,那么恭喜你配置成功,否则,你就要查看错误信息来纠正错误,下面是一些常见的错误:

     

    第一个应用程序

      现在已经确认数据库连接正常工作了,让我们来创建一个 Django app-一个包含模型,视图和Django代码,并且形式为独立Python包的完整Django应用。

        在这里要先解释一些术语,初学者可能会混淆它们。 在第二章我们已经创建了 project , 那么 project 和 app之间到底有什么不同呢?它们的区别就是一个是配置另一个是 代码:

      一个project包含很多个Django app以及对它们的配置。

      技术上,project的作用是提供配置文件,比方说哪里定义数据库连接信息, 安装的app列表,TEMPLATE_DIRS ,等等。

      例如,Django本身内建有一些app,例如注释系统和自动管理界面。 app的一个关键点是它们是很容易移植到其他project和被多个project复用。

      对于如何架构Django代码并没有快速成套的规则。 如果你只是建造一个简单的Web站点,那么可能你只需要一个app就可以了; 但如果是一个包含许多不相关的模块的复杂的网站,例如电子商务和社区之类的站点,那么你可能需要把这些模块划分成不同的app,以便以后复用。不错,你可以不用创建app,这一点应经被我们之前编写的视图函数的例子证明了 。 在那些例子中,我们只是简单的创建了一个称为views.py的文件,编写了一些函数并在URLconf中设置了各个函数的映射。 这些情况都不需要使用apps。但是,系统对app有一个约定: 如果你使用了Django的数据库层(模型),你 必须创建一个Django app。 模型必须存放在apps中。 因此,为了开始建造 我们的模型,我们必须创建一个新的app。

      在“ mysite” 项目文件下输入下面的命令来创建“ books” app: 

    1 python manage.py startapp books

      这个命令并没有输出什么,它只在 mysite 的目录里创建了一个 books 目录。 让我们来看看这个目录的内容:

    1 books/
    2     __init__.py
    3     admin.py
    4     models.py
    5     tests.py
    6     views.py

      这个目录包含了这个app的模型和视图。使用你最喜欢的文本编辑器查看一下 models.py 和 views.py 文件的内容(博主大爱Sublime Text2)。 它们都是空的,除了 models.py 里有一个 import。这就是你Django app的基础。

    第一个模型

      在此次博文中,我们把注意力放在一个基本的 书籍/作者/出版商 数据库结构上。 我们这样做是因为 这是一个众所周知的例子,很多SQL有关的书籍也常用这个举例。

      第一步是用Python代码来描述它们。 打开由“ startapp” 命令创建的models.py 并输入下面的内容:  

     1 from django.db import models
     2 
     3 class Publisher(models.Model):
     4     name = models.CharField(max_length=30)
     5     address = models.CharField(max_length=50)
     6     city = models.CharField(max_length=60)
     7     state_province = models.CharField(max_length=30)
     8     country = models.CharField(max_length=50)
     9     website = models.URLField()
    10 
    11 class Author(models.Model):
    12     first_name = models.CharField(max_length=30)
    13     last_name = models.CharField(max_length=40)
    14     email = models.EmailField()
    15 
    16 class Book(models.Model):
    17     title = models.CharField(max_length=100)
    18     authors = models.ManyToManyField(Author)
    19     publisher = models.ForeignKey(Publisher)
    20     publication_date = models.DateField()

      让我们来快速讲解一下这些代码的含义。 首先要注意的事是每个数据模型都是 django.db.models.Model 的子类。它的父类 Model 包含了所有必要的和数据库交互的方法,并提供了一个简洁漂亮的定义数据库字段的语法。 信不信由你,这些就是我们需要编写的通过Django存取基本数据的所有代码。

        事实上,正如过一会儿我们所要展示的,Django 可以自动生成这些 CREATE TABLE 语句。

    模型安装

      完成这些代码之后,现在让我们来在数据库中创建这些表。 要完成该项工作,第一步是在 Django 项目中 激活这些模型。 将 books app 添加到配置文件的已安装应用列表中即可完成此步骤。

      再次编辑 settings.py 文件, 找到 INSTALLED_APPS 设置。 INSTALLED_APPS 告诉 Django 项目哪些 app 处于激活状态。 缺省情况下如下所示: 

    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    )

       把这四个设置前面加#临时注释起来。 (这四个app是经常使用到的,我们将在后续章节里讨论如何使用它们)。同时,注释掉MIDDLEWARE_CLASSES的默认设置条目,因为这些条目是依赖于刚才我们刚在INSTALLED_APPS注释掉的apps。 然后,添加“books”到“ INSTALLED_APPS”的末尾,此时设置的内容看起来应该是这样的: 

     1 INSTALLED_APPS = (
     2     'mysite',
     3     'books',
     4     #'django.contrib.admin',
     5     #'django.contrib.auth',
     6     #'django.contrib.contenttypes',
     7     #'django.contrib.sessions',
     8     #'django.contrib.messages',
     9     #'django.contrib.staticfiles',
    10 )
       PS:就像我们在上一章设置TEMPLATE_DIRS所提到的逗号,同样在INSTALLED_APPS的末尾也需添加一个逗号,因为这是个单元素的元组。 另外,本书的作者喜欢在 每一个 tuple元素后面加一个逗号,不管它是不是 只有一个元素。 这是为了避免忘了加逗号,而且也没什么坏处。
      现在我们可以创建数据库表了。 首先,用下面的命令验证模型的有效性: 
    1 python manage.py validate

       validate 命令检查你的模型的语法和逻辑是否正确。 如果一切正常,你会看到 0 errors found 消息。如果出错,请检查你输入的模型代码。 错误输出会给出非常有用的错误信息来帮助你修正你的模型。一旦你觉得你的模型可能有问题,运行 python manage.py validate 。 它可以帮助你捕获一些常见的模型定义错误。模型确认没问题了,运行下面的命令来生成 CREATE TABLE 语句:

    1 python manage.py sqlall books
      在这个命令行中, books 是app的名称。 和你运行 manage.py startapp 中的一样。执行之后,输出如下:
      
     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" (
    20     "id" serial NOT NULL PRIMARY KEY,
    21     "title" varchar(100) NOT NULL,
    22     "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id") DEFERRABLE INITIALLY DEFERRED,
    23     "publication_date" date NOT NULL
    24 )
    25 ;
    26 CREATE TABLE "books_book_authors" (
    27     "id" serial NOT NULL PRIMARY KEY,
    28     "book_id" integer NOT NULL REFERENCES "books_book" ("id") DEFERRABLE INITIALLY DEFERRED,
    29     "author_id" integer NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INITIALLY DEFERRED,
    30     UNIQUE ("book_id", "author_id")
    31 )
    32 ;
    33 CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id");
    34 COMMIT;

       sqlall 命令并没有在数据库中真正创建数据表,只是把SQL语句段打印出来,这样你可以看到Django究竟会做些什么。 如果你想这么做的话,你可以把那些SQL语句复制到你的数据库客户端执行,或者通过Unix管道直接进行操作(例如,`` python manager.py sqlall books | psql mydb`` )。不过,Django提供了一种更为简易的提交SQL语句至数据库的方法:"syncdb" 命令:

    1 python manage.py syncdb

       syncdb 命令是同步你的模型到数据库的一个简单方法。 它会根据 INSTALLED_APPS 里设置的app来检查数据库, 如果表不存在,它就会创建它。 需要注意的是, syncdb 并 不能将模型的修改或删除同步到数据库;如果你修改或删除了一个模型,并想把它提交到数据库,syncdb并不会做出任何处理。

    基本数据访问

      一旦你创建了模型,Django自动为这些模型提供了高级的Python API。 运行 python manage.py shell 并输入下面的内容试试看:

     1 >>> from books.models import Publisher
     2 >>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',
     3 ...     city='Berkeley', state_province='CA', country='U.S.A.',
     4 ...     website='http://www.apress.com/')
     5 >>> p1.save()
     6 >>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.',
     7 ...     city='Cambridge', state_province='MA', country='U.S.A.',
     8 ...     website='http://www.oreilly.com/')
     9 >>> p2.save()
    10 >>> publisher_list = Publisher.objects.all()
    11 >>> publisher_list
    12 [<Publisher: Publisher object>, <Publisher: Publisher object>]

      这短短几行代码干了不少的事。 这里简单的说一下:

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

      这里有一个值得注意的地方,在这个例子可能并未清晰地展示。 当你使用Django modle API创建对象时Django并未将对象保存至数据库内,除非你调用"save()" 方法: 

    1 p1 = Publisher(...)
    2 # At this point, p1 is not saved to the database yet!
    3 p1.save()
    4 # Now it i

      如果需要一步完成对象的创建与存储至数据库,就使用 "objects.create()" 方法。 下面的例子与之前的例子等价:

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

      当我们打印整个publisher列表时,我们没有得到想要的有用信息。

    1 [<Publisher: Publisher object>, <Publisher: Publisher object>]

      我们可以简单解决这个问题,只需要为Publisher 对象添加一个方法 __unicode__() 。 __unicode__() 方法告诉Python如何将对象以unicode的方式显示出来。 为以上三个模型添加__unicode__()方法后,就可以看到效果了:

     1 from django.db import models
     2 
     3 class Publisher(models.Model):
     4     name = models.CharField(max_length=30)
     5     address = models.CharField(max_length=50)
     6     city = models.CharField(max_length=60)
     7     state_province = models.CharField(max_length=30)
     8     country = models.CharField(max_length=50)
     9     website = models.URLField()
    10 
    11     def __unicode__(self):
    12         return self.name
    13 
    14 class Author(models.Model):
    15     first_name = models.CharField(max_length=30)
    16     last_name = models.CharField(max_length=40)
    17     email = models.EmailField()
    18 
    19     def __unicode__(self):
    20         return u'%s %s' % (self.first_name, self.last_name)
    21 
    22 class Book(models.Model):
    23     title = models.CharField(max_length=100)
    24     authors = models.ManyToManyField(Author)
    25     publisher = models.ForeignKey(Publisher)
    26     publication_date = models.DateField()
    27 
    28     def __unicode__(self):
    29         return self.title

      就象你看到的一样, __unicode__() 方法可以进行任何处理来返回对一个对象的字符串表示。 PublisherBook对象的__unicode__()方法简单地返回各自的名称和标题,Author对象的__unicode__()方法则稍微复杂一些,它将first_namelast_name字段值以空格连接后再返回。

      以上就是这次博文的主要内容,to be continued···

     

    评论
  • 相关阅读:
    奇数阶魔方问题
    《DSP using MATLAB》示例9.3
    《DSP using MATLAB》示例9.2
    《DSP using MATLAB》示例9.1
    找个目标很重要
    《DSP using MATLAB》示例Example 8.30
    《DSP using MATLAB》示例Example 8.29
    《DSP using MATLAB》示例Example 8.28
    《DSP using MATLAB》示例Example 8.27
    《DSP using MATLAB》示例Example 8.26
  • 原文地址:https://www.cnblogs.com/voidy/p/3996410.html
Copyright © 2011-2022 走看看