zoukankan      html  css  js  c++  java
  • 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、插入更新数据













  • 相关阅读:
    自考新教材-p240_2
    自考新教材-p243_5_(1)
    自考新教材-p242_4
    自考新教材-p233
    自考新教材-p230
    Spring入门(9)-AOP初探
    MongoDB的备份与恢复
    JVM基础知识(1)-JVM内存区域与内存溢出
    Spring入门(8)-基于Java配置而不是XML
    Spring入门(7)-自动检测Bean
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3076827.html
Copyright © 2011-2022 走看看