Django项目实践3 - Django模型(view-数据库)

来源:互联网 发布:淘宝卖家货到付款骗局 编辑:程序博客网 时间:2024/05/22 10:22

http://blog.csdn.net/pipisorry/article/details/45061579

Django 模型

{数据和逻辑能够彻底地分开}

视图负责处理一些主观逻辑,然后返回响应结果。在当代 Web 应用中,主观逻辑经常牵涉到与数据库的交互。 数据库驱动网站 在后台连接数据库服务器,从中取出一些数据,然后在 Web 页面用漂亮的格式展示这些数据。 这个网站也可能会向访问者提供修改数据库数据的方法。许多复杂的网站都提供了以上两个功能的某种结合。 例如 Amazon.com 就是一个数据库驱动站点的良好范例。 本质上,每个产品页面都是数据库中数据以 HTML格式进行的展现,而当你发表客户评论时,该评论被插入评论数据库中。由于先天具备 Python 简单而强大的数据库查询执行方法,Django 非常适合开发数据库驱动网站。

Django 对各种数据库提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。Django 为这些数据库提供了统一的调用API。

DRY和SHY都是为了达到松耦合,为了提高程序的可维护性。其中Dry强调了共性,提取整合共性,比如类的复用和继承。Shy则强调了个性,避免一个类或者模块与其他产生复杂的交叉关系。 “Don't Repeat Yourself”


在 Django 中使用 MySQL

 MySQL 是 Web 应用中最常用的数据库。[MySQL 教程]

首先下载并安装MySQL

django要求MySQL4.0或更高的版本。 3.X 版本不支持嵌套子查询和一些其它相当标准的SQL语句。[Mysql数据库安装及配置]

Note:

1. 可能还需要从 http://www.djangoproject.com/r/python-mysql/ 下载安装 MySQLdb 。如果用的是python3从这下载mysqldb for python3

2. 如果你正在使用Linux,检查下你系统的包管理器是否提供了叫做python-mysql,python-mysqldb,myspl-python或者相似的包。

3. 使用python3自带的数据库SQLite。教程见[Django Documentation - Writing your first Django app, part 1 - Database setup]

数据库配置

初始配置

我们需要告诉Django使用什么数据库以及如何连接数据库。

假定你已经完成了数据库服务器的安装和激活,并且已经在其中创建了数据库(例如,用 CREATE DATABASE books;)。 如果你使用SQLite,不需要这步安装,因为SQLite使用文件系统上的独立文件来存储数据。

数据库配置也是在Django的配置文件里,缺省 是 settings.py

<span style="color:#33CC00;"><strong><span style="background-color:rgb(255,255,255)">DATABASES = {    'default': {        'ENGINE': 'django.db.backends.mysql',        'NAME': 'books',        #这里不要用绝对路径!        'USER': 'pipi',        'PASSWORD': '********',        'HOST': '',        'PORT': '',    }}</span></strong></span>

Note:

1. 配置文件说明:

DATABASE_USER 告诉 Django 用哪个用户连接数据库。 例如: 如果用SQLite,空白即可。

DATABASE_PASSWORD 告诉Django连接用户的密码。 SQLite 用空密码即可。

DATABASE_HOST 告诉 Django 连接哪一台主机的数据库服务器。 如果数据库与 Django 安装于同一台计算机(即本机),可将此项保留空白。如果你使用SQLite,此项留空。此处的 MySQL 是一个特例。

2. 如果使用的是 MySQL 且该项设置值由斜杠('/' )开头,MySQL 将通过 Unix socket 来连接指定的套接字,例如:DATABASE_HOST = '/var/run/mysql'

3. 上面包含数据库名称和用户的信息,它们与MySQL中对应数据库和用户的设置相同。Django根据这一设置,与MySQL中相应的数据库和用户连接起来。

4. 当你编辑 settings.py 时,将 TIME_ZONE 修改为你所在的时区。默认值是美国中央时区(芝加哥)。

配置纲要

DATABASE_ENGINE 告诉Django使用哪个数据库引擎。 如果你在 Django 中使用数据库,DATABASE_ENGINE 必须是 Table 5-1 中所列出的值。


设置数据库所需适配器`` postgresql``PostgreSQLpsycopg 1.x版,http://www.djangoproject.com/r/python-pgsql/1/。postgresql_psycopg2PostgreSQLpsycopg 2.x版,http://www.djangoproject.com/r/python-pgsql/。mysqlMySQLMySQLdb ,http://www.djangoproject.com/r/python-mysql/.sqlite3SQLite如果使用Python 2.5+则不需要适配器。 否则就使用 pysqlite ,http://www.djangoproject.com/r/python-sqlite/。oracleOraclecx_Oracle ,http://www.djangoproject.com/r/python-oracle/.要注意的是无论选择使用哪个数据库服务器,都必须下载和安装对应的数据库适配器。

配置数据库连接MySQL

安装对应的mysql数据库插件。

MySQLdb还不支持python3,所以用的是替代品PyMySQL。

1. pip安装pymysql适配器

pip install pymysql

2. 下载pyMysql安装包并安装:

python setup.py install

Note:

1.系统是ubuntu14.04,安装pymysql非常简单:$ sudo pip3 install PyMySQL

2. 安装完成后可能要重启pycharm, import pymysql才不会出错。

3. pymysql用法参考[Example]

在上面建好的django项目的init.py中加入

import pymysqlpymysql.install_as_MySQLdb()

测试配置

在`` VoteSite`` 项目目录下执行上章所提到的`` python manage.py shell`` 来进行测试。

输入下面这些命令来测试你的数据库配置:

<span style="color:#33CC00;"><strong>from django.db import connectioncursor = connection.cursor()</strong></span>
如果没有显示什么错误信息,那么你的数据库配置是正确的。

http://blog.csdn.net/pipisorry/article/details/45061579



创建app

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

project 和app 之间的区别

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

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

一个app是一套Django功能的集合,通常包括模型和视图,按Python的包结构的方式存在。例如,Django本身内建有一些app,例如注释系统和自动管理界面。 app的一个关键点是它们是很容易移植到其他project和被多个project复用。

对于如何架构Django代码并没有快速成套的规则。 如果你只是建造一个简单的Web站点,那么可能你只需要一个app就可以了; 但如果是一个包含许多不相关的模块的复杂的网站,例如电子商务和社区之类的站点,那么你可能需要把这些模块划分成不同的app,以便以后复用。

你可以不用创建app,这一点应经被我们之前编写的视图函数的例子证明了 。 在那些例子中,我们只是简单的创建了一个称为views.py的文件,编写了一些函数并在URLconf中设置了各个函数的映射。但是,系统对app有一个约定: 如果你使用了Django的数据库层(模型),你 必须创建一个Django app。 模型必须存放在apps中。

创建app

在`` VoteSite`` 项目文件下输入下面的命令来创建`` books`` app:

<span style="color:#33CC00;"><strong>python manage.py startapp books</strong></span>

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

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

这个目录包含了这个app的模型和视图。它们都是空的,除了 models.py 里有一个 import。

定义模型

Django模型是用Python代码形式表述的数据在数据库中的定义。 对数据层来说它等同于 CREATE TABLE 语句,只不过执行的是Python代码而不是 SQL,而且还包含了比数据库字段定义更多的含义。 Django用模型在后台执行SQL代码并把结果用Python的数据结构来描述。Django也使用模型来呈现SQL无法处理的高级概念。

用Python SQL来定义数据模型的原因:

自省(运行时自动识别数据库)会导致过载和有数据完整性问题。 为了提供方便的数据访问API, Django需要以 某种方式 知道数据库层内部信息,有两种实现方式。第一种方式是用Python明确地定义数据模型,第二种方式是通过自省来自动侦测识别数据模型。第二种方式看起来更清晰,因为数据表信息只存放在一个地方-数据库里,但是会带来一些问题。 首先,运行时扫描数据库会带来严重的系统过载。 第二,某些数据库,尤其是老版本的MySQL,并未完整存储那些精确的自省元数据。

保持用Python的方式思考会避免你的大脑在不同领域来回切换。 尽可能的保持在单一的编程环境/思想状态下可以帮助你提高生产率。

把数据模型用代码的方式表述来让你可以容易对它们进行版本控制。 这样,你可以很容易了解数据层 的变动情况。

SQL只能描述特定类型的数据字段。 例如,大多数数据库都没有专用的字段类型来描述Email地址、URL。 而用Django的模型可以做到这一点。 好处就是高级的数据类型带来更高的效率和更好的代码复用。

SQL还有在不同数据库平台的兼容性问题。 发布Web应用的时候,使用Python模块描述数据库结构信息可以避免为MySQL, PostgreSQL, and SQLite编写不同的CREATETABLE

当然,这个方法也有一个缺点,就是Python代码和数据库表的同步问题。 如果你修改了一个Django模型, 你要自己来修改数据库来保证和模型同步。 我们将在稍后讲解解决这个问题的几种策略。

最后,Django提供了实用工具来从现有的数据库表中自动扫描生成模型。 这对已有的数据库来说是非常快捷有用的。

定义模型

基本的 书籍/作者/出版商 数据库结构。假定下面的这些概念、字段和关系:

  • 一个作者有姓,有名及email地址。

  • 出版商有名称,地址,所在城市、省,国家,网站。

  • 书籍有书名和出版日期。 它有一个或多个作者(和作者是多对多的关联关系[many-to-many]);只有一个出版商(和出版商是一对多的关联关系[one-to-many],也被称作外键[foreign key])

打开由`` startapp`` 命令创建的models.py 并输入:

<span style="color:#33CC00;"><strong>from django.db import modelsclass 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()</strong></span>

Note:

1. 它的父类 Model 包含了所有必要的和数据库交互的方法,并提供了一个简洁漂亮的定义数据库字段的语法。

2. 每个模型相当于单个数据库表,每个属性也是这个表中的一个字段。 属性名就是字段名,它的类型(例如 CharField )相当于数据库的字段类型 (例如 varchar )。例如, Publisher 模块等同于下面这张表(用PostgreSQL的CREATETABLE 语法描述):

<span style="color:#C0C0C0;">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);</span>

Django 可以自动生成这些 CREATETABLE 语句。

3. “每个数据库表对应一个类”这条规则的例外情况是多对多关系。 在我们的范例模型中, Book 有一个 多对多字段 叫做authors 。 该字段表明一本书籍有一个或多个作者,但Book 数据库表却并没有 authors 字段。相反,Django创建了一个额外的表(多对多连接表)来处理书籍和作者之间的映射关系。

4. 我们并没有显式地为这些模型定义任何主键。 除非你单独指明,否则Django会自动为每个模型生成一个自增长的整数主键字段每个Django模型都要求有单独的主键id

·

激活和安装模型

{在数据库中创建这些表}

将 books app 添加到配置文件的已安装应用列表中

settings.py >  INSTALLED_APPS 设置。 INSTALLED_APPS 告诉 Django 项目哪些 app 处于激活状态。 

添加`` ‘VoteSite.books’`` 到`` INSTALLED_APPS`` 的末尾

<span style="background-color:rgb(255,255,255)">INSTALLED_APPS</span> = (    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    <strong><span style="color:#33CC00;">'books',</span></strong>    #如果当前路径就在VoteSite中,就可以去掉前缀VoteSite.)

Note:就像我们在上一章设置TEMPLATE_DIRS所提到的逗号,同样在INSTALLED_APPS的末尾也需添加一个逗号,因为这是个单元素的元组。

将这些更改存储为迁移文件

告诉Django,你已经对模型做了一些更改(在这个例子中,你新建了一些模型)。

$ python manage.py makemigrations books

Note:

1. Django通过迁移文件来保存你对模型的改动(这些改动以后会使数据库表也发生相应的变化)-迁移文件在硬盘上真实地存在着。你能够阅读这些迁移文件;比如这次改动所生成的迁移文件books/migrations/0001_initial.py。但当每次Django生成迁移文件的时候,你不用都去读它们。它们只是被设计成人类可以进行编辑的格式,以便在Django改动数据库表之前,你可以轻微地手动修改Django的一些具体行为。

2. 有一个命令可以运行这些迁移文件,并且自动更新你的数据库表-它叫做migrate,一会儿会用到。

看一下迁移行为将会执行哪些SQL语句

sqlmigrate命令需要输入迁移文件的名字作为参数,它会返回迁移行为所需执行的SQL语句:

$ python manage.py sqlmigrate books 0001

输出:

BEGIN;CREATE TABLE ...CREATE INDEX ...ALTER TABLE ...  ADD CONSTRAINT ...COMMIT;

Note:

1. 输出的具体内容会因为你使用的数据库的不同而不同。

2. 数据表的名称是自动生成的。这个名称由app的名字和模型名字的小写字母组合而成。(你可以重写此行为。)

3. 主键(IDs)是自动添加的。(你也可以重写此行为。)

4. 按照惯例,Django会在外键的字段名后面添加"_id"。(是的,你依然可以重写此行为)

5. 外键关系由FOREIGN KEY语句显示声明。不用在意DEFERRABLE部分;它只是告诉PostgreSQL直到事务的最后再执行外键关联。

6. 这些SQL语句是针对你所使用的数据库量身定做的,会为你自动处理某些数据库所特有的字段。例如,auto_increment(MySQL),serial(PostgreSQL),或者integerprimarykeyautoincrement(SQLite)。在处理字段名的引号时也是如此。例如,有时使用双引号,有时使用单引号。

7. sqlmigrate命令并不会真正改变你的数据库-它只是把Django要做的事打印在屏幕上,来让你知道。这个语句对于检查Django将要进行的数据库操作是非常有用的。或者你拥有数据库管理员,并且想要获得这些SQL脚本来自己执行操作,这个语句也十分有用。

8. 如果你感兴趣的话,也可以运行pythonmanage.pycheck命令;它能在你没有执行迁移或者没有接触到数据库时,检查你的项目中是否存在问题。

在数据库中创建模型所对应的数据表

运行migrate命令:

E:\mine\python_workspace\VoteSite>python manage.py migrateOperations to perform:  Apply all migrations: books, admin, sessions, auth, contenttypesRunning migrations:  Applying contenttypes.0001_initial... OK  Applying auth.0001_initial... OK  Applying admin.0001_initial... OK  Applying books.0001_initial... OK  Applying sessions.0001_initial... OK

Note:

1. migrate是干什么的呢,简单来说就是它可以让我们在修改Model后可以在不影响现有数据的前提下重建表结构。

2. migrate命令会找出所有还没有被应用的迁移文件(Django使用数据库中的一个叫做django_migrations的特殊的表来追踪哪些迁移文件已经被应用过了),并且运行他们来更新你的数据库-本质上来讲,就是使数据库表和改动后的模型进行同步。

3. 迁移功能是非常有用的。可以让你在开发过程中,使用现有的模型一段时间之后还能对其进行修改。并且不用删除现有数据库或者数据库表,也不用重新生成。-它致力于在程序运行过程中,不丢失数据的情况下升级你的数据库。

4.A New Field Means a New Migration

5. django <1.7使用第三方south做数据库迁移,>=1.7将south整合到django里,因此自带数据库迁移功能。这里是>=1.7的数据库迁移。django>=1.7数据库迁移只有三个命令

migrate,用来迁移数据库。用法:migrate app

makemigrations,用来检测数据库变更和生成数据库迁移文件。用法:makemigratioins app

sqlmigrate,用来把数据库迁移文件转换成数据库语言(displays the SQL statements for a migratioin.)用法:sqlmigrate app migration,比如makemigrations生成了0001_initial.py,就用sqlmigrate app 0001_intial,这里0001_initial就是migration参数。

一般如果某次migration使用sqlmigrate没有提示错误,那么在migrate时就能成功。如果migrate失败了,可以用sqlmigrate调试。

[django数据库迁移sqlmigrate调试]

记住这三步来实现模型的变更:
  • 修改你的模型(在models.py中)。
  • 运行python manage.py makemigrations命令为这些改动创建迁移文件。
  • 运行python manage.py migrate命令将这些改动应用到数据库中。

Note:

1.django1.7? use makemigrations and migrate instead of syncdb

2. 将生成和应用迁移文件的命令分成好几个命令来执行是因为你可能需要将迁移文件提交到你的版本控制系统中,并且使用你的应用来管理他们;他们不仅可以使你的开发变得简单,对其他开发者或者在生产环境中也是非常有用的。


sqllite中创建数据库表

首先,用下面的命令验证模型的有效性:

<span style="color:#CCCCCC;">python manage.py validate</span>

validate 命令检查你的模型的语法和逻辑是否正确。 如果一切正常,你会看到System check identified no issues (0 silenced).消息。

生成 CREATE TABLE 语句(如果你使用的是Unix,那么可以启用语法高亮):

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

执行这个命令后,将看到类似以下的内容:

<span style="color:#CCCCCC;">Creating table books_publisherCreating table books_authorCreating table books_bookInstalling index for books.Book model</span>

syncdb 命令是同步你的模型到数据库的一个简单方法。 它会根据INSTALLED_APPS 里设置的app来检查数据库, 如果表不存在,它就会创建它。 需要注意的是,syncdb不能将模型的修改或删除同步到数据库;如果你修改或删除了一个模型,并想把它提交到数据库,syncdb并不会做出任何处理。 (更多内容请查看本章最后的“修改数据库的架构”一段。)

如果你再次运行 python manage.py syncdb ,什么也没发生,因为你没有添加新的模型或者 添加新的app。因此,运行pythonmanage.pysyncdb总是安全的,因为它不会重复执行SQL语句。

如果你有兴趣,花点时间用你的SQL客户端登录进数据库服务器看看刚才Django创建的数据表。 你可以手动启动命令行客户端(例如,执行PostgreSQL的`` psql`` 命令),也可以执行 `` python manage.py dbshell`` ,这个命令将依据`` DATABASE_SERVER`` 的里设置自动检测使用哪种命令行客户端。 常言说,后来者居上。


Django模型(字段及命令行和admin上进行数据库操作)



views.py中进行数据库操作

接下来我们在 HelloWorld 目录中添加 testdb.py 文件,并修改urls.py:

from django.conf.urls import *from HelloWorld.view import hellofrom HelloWorld.testdb import testdburlpatterns = patterns("",        ('^hello/$', hello),        ('^testdb/$', testdb),)

添加数据

# -*- coding: utf-8 -*-from django.http import HttpResponsefrom TestModel.models import Test# 数据库操作def testdb(request):test1 = Test(name='pipi')test1.save()return HttpResponse("<p>数据添加成功!</p>")

访问http://192.168.45.3:8000/testdb/ 就可以看到数据添加成功的提示。

获取数据

# -*- coding: utf-8 -*-from django.http import HttpResponsefrom TestModel.models import Test# 数据库操作def testdb(request):# 初始化response = ""response1 = ""list = Test.objects.all()response2 = Test.objects.filter(id=1) response3 = Test.objects.get(id=1) Test.objects.order_by('name')[0:2]Test.objects.order_by("id")Test.objects.filter(name="w3cschool.cc").order_by("id")# 输出所有数据for var in list:response1 += var.name + " "response = response1return HttpResponse("<p>" + response + "</p>")


view.py中使用 Django 数据库 API视图调用数据库数据

from django.shortcuts import render_to_response<span style="color:#66d9ef;font-style:italic">def </span><span style="color:#a6e22e;">news</span>(<span style="color:#fd971f;font-style:italic">request</span>)<span style="color:#f92672;">:</span><span style="color:#f92672;">    </span><span style="color:#75715e;"># newss = News.objects.all()</span><span style="color:#75715e;">    </span>newss <span style="color:#f92672;">= </span>News.objects.order_by(<span style="color:#e6db74;">'time_stamp'</span>)    context <span style="color:#f92672;">= </span>{<span style="color:#e6db74;">'newss'</span><span style="color:#f92672;">:</span>newss}    <span style="color:#66d9ef;font-style:italic">return </span>render_to_response(<span style="color:#e6db74;">'bigdata/news.html'</span>, context)
Note:小技巧: return render_to_response('bigdata/team-pi.html', locals())
locals()就是代表函数中所有变量的字典,直接代替context.
下篇:Django项目实践3 - Django站点管理
from:http://blog.csdn.net/pipisorry/article/details/45061579
ref:Chapter 5. Saving User Input
建立一个更高级别的查询 API:正确使用Django ORM 的方式


1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 弯腰时间久了腰疼怎么办 斗鱼pk输的怎么办 领导当着人骂我怎么办 被老板骂了应该怎么办 三星s7关机键掉了怎么办 主播遇到黑粉怎么办 在工作单位突然死亡怎么办 孕7月半夜脚抽筋怎么办 上单对上两个射手怎么办 游戏本玩游戏掉帧怎么办 手机开直播很卡怎么办 小孩小鸡被虫子咬了怎么办 小鸡仔不吃食了怎么办 小鸡的腿瘸了怎么办 在境外住酒店钱被偷了怎么办 一加6屏幕辣眼睛怎么办 棉质衣服皱了怎么办 洗完衣服皱了怎么办 穿衬衫袖子很皱怎么办 洗完衣服有褶皱怎么办 麻料裤子容易皱怎么办 苹果手机邮件删了怎么办 飞猪12306登录不上怎么办 邮箱被别人绑定12306怎么办 白名单一个地址也没怎么办 12306忘记用户名和密码怎么办 12306忘了用户名和密码怎么办 12306注册后忘了密码怎么办 12306帐号忘了密码怎么办 12306忘了密码和手机号怎么办 12306账号密码邮箱忘了怎么办 注册12306账号没有邮箱怎么办 12306忘了用户名和邮箱怎么办 12306忘记用户名和邮箱怎么办 12306证件号码已被注册怎么办 12306忘记手机号和邮箱怎么办 发邮件被对方服务器退回怎么办 铁路12306显示已注册怎么办 qq密码太长输不进去怎么办 淘宝买家收货地址填写不全怎么办 护士电子注册账户未激活怎么办