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、插入更新数据













  • 相关阅读:
    SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程'sys.sp_OACreate' 的访问
    谷歌浏览器扩展程序manifest.json参数详解
    获取天气api
    UVA 10385 Duathlon
    UVA 10668 Expanding Rods
    UVALIVE 3891 The Teacher's Side of Math
    UVA 11149 Power of Matrix
    UVA 10655 Contemplation! Algebra
    UVA 11210 Chinese Mahjong
    UVA 11384 Help is needed for Dexter
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3076827.html
Copyright © 2011-2022 走看看