Django -- 模型(数据库层)

web应用中,主观逻辑(视图处理)经常牵涉与数据库的交互。数据库驱动网站在后台连接数据库,从中取数据,然后甩漂亮界面展现在web端。许多复杂的网站都提供以上两种功能的结合(如Amazon.com),而Python天生具备简单强大的数据库查询执行方法,很适合开发这类数据库驱动网站。

他就是下面介绍的Django数据库层!

【 硬 编 码 链 接 数 据 库 】

cat ~/HelloWorld/HelloWorld/view.py

from django.shortcuts import render_to_response
import MySQLdb
def book_list(request):
    db = MySQLdb.connect(user=‘me‘, db=‘mydb‘, passwd=‘secret‘, host=‘localhost‘)
    cursor = db.cursor()
    cursor.execute(‘SELECT name FROM books ORDER BY name‘)
    names = [row[0] for row in cursor.fetchall()]
    db.close()
return render_to_response(‘book_list.html‘, {‘names‘: names})

弊端:此方法虽可用,但是我们将参数配置直接硬编码到视图函数,显然犯了前两节相同的错误;如果我们改一个参数、改一种数据库、换个执行语句等等,都会引起大范围的改动。

那我们能不能像上节那样创建模板,其实django提供了更简单直接的方式:数据库API

===============================================================================================

MVC架构模式、MTV 开发模式

Django 设计遵循松耦合原则,修改某部分不影响其他部分。视图函数中通过了模板系统将业务逻辑和表现逻辑分隔,数据库层也应如此。

MVC 架构模式:即数据存取逻辑(model)、表现逻辑(view)、业务逻辑(controller)的组合

其中 C 由框架自行处理,django更关注的是模型(model)、模板(template)、视图(views),也被称MTV框架

M:数据存取,处理与数据相关所有事务;

T:表现层,处理与表现相关的决定,比如页面如何显示;

V:视图,处理存取模型和调取模板的逻辑,可看做模型与模板的桥梁。

注: django认为视图用来展现数据,控制器是如何展示;其他框架认为控制器用来展现数据,视图决定如何展现。

================================================================================================

上面所说的数据库API,其实就是更改django配置文件,通过配置文件的接口进数据库。

数据库 DATABASE_ENGINE 适配器
PostgreSQL postgresql http://www.djangoproject.com/r/python-pgsql/1/
PostgreSQL postgresql_psycopg2 http://www.djangoproject.com/r/python-pgsql/
MySQL mysql http://www.djangoproject.com/r/python-mysql/
SQLite sqlite3 http://www.djangoproject.com/r/python-sqlite/
Oracle oracle http://www.djangoproject.com/r/python-oracle/
vim ~/HelloWorld/HelloWorld/settings.py

DATABASES = {
    ‘default‘: {
    ‘ENGINE‘: ‘django.db.backends.mysql‘,
    ‘NAME‘: ‘django‘,
    ‘USER‘: ‘django‘,
    ‘PASSWORD‘: ‘django123‘,
    ‘HOST‘:‘localhost‘,
    ‘PORT‘:‘3306‘,
}
}

之后去数据库建一个django库,并给django用户赋值。然后测试一下(没有报错信息即配置成功,并能链接到mysql的django库了,关于django报错信息,请参考下一节):

启动shell界面:python manage.py  shell

>>> from django.db import connection

>>> cursor = connection.cursor()

【应用程序app 与 模型model.py】

第 一 个 app 

Django规定:如果使用了django数据库层(或模型),必须要创建django app,把模型放在里面;应用程序app是项目project组成部分。

python manage.py startapp mysql_django    #创建mysql_django app

创建好app,将app加入到HelloWorld project中

vim ~/HelloWorld/HelloWorld/settings.py

INSTALLED_APPS = [
‘django.contrib.admin‘,
‘django.contrib.auth‘,
‘django.contrib.contenttypes‘,
‘django.contrib.sessions‘,
‘django.contrib.messages‘,
‘django.contrib.staticfiles‘,
**   ‘mysql_django‘,      #逗号结尾,也可用点语法 HelloWorld.mysql_django
]

第 一 个 模 型 

其实django模型就是以python代码表述数据库中表结构

vim ~/HelloWorld/mysql_django/models.py

from django.db import models

class Publisher(models.Model): #CREATE TABLE "books_publisher"("id" serial NOT NULL PRIMARY KEY,
    name = models.CharField(max_length=30)   #"name" varchar(30) NOT NULL,
   address = models.CharField(max_length=50) #"address" varchar(50) NOT NULL,
   city = models.CharField(max_length=60)    #"city" varchar(60) NOT NULL,
   state_province = models.CharField(max_length=30) #"state_province" varchar(30) NOT NULL,
   country = models.CharField(max_length=50) #"country" varchar(50) NOT NULL,
   website = models.URLField()        #"website" varchar(200) NOT NULL );
                        
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()

代码解读:

1、首先每个数据模型都是django.db.models.Model的子类,父类Model包含所有与数据库交互的必要方法;

2、每个模型相当于数据库表,每个属性即字段,类型(CharField)相当于字段类型(varchar)

3、Publisher举例,python语法即等于右边的数据库语法。

4、定义了出版商、作者、书籍的一些内容。

当完成以上模型建表后,并将其app加入到了项目,接下来就开始执行建表了

a、检查语法错误(django1.9.0版本以下用 python manage.py validate)

python  manage.py  check

b、生成数据库迁移文件(在app下的migrations下生成0001文件,更改后执行,生成0002....迁移文件)

python  manage.py  makemigrations mysql_django

c、同步数据库(老版本用python manage.py syncdb,即把迁移文件转换语法同步数据库[库名app名_类名])

python  manage.py  migrate

d、转换成 SQL 语言(老版本 python manage.py sqlall mysql_django,查看转换后的mysql语法)

python  manage.py  sqlmigrate  mysql_django  0001

【Python 与 数 据 库 API】

进入:python manage.py shell

>>> from mysql_django.models  import Publisher      #导入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()                    #调用了save()方法,才能真正将p1插入数据库

>>> 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/‘)    #objects.create()方法可直接将数据插入数据库

>>> publisher_list = Publisher.objects.all()    #从数据库取出出版商信息==select

>>> publisher_list

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

插入两个数据后,讲道理Publisher.objects.all()方法会取出Publisher类的对象,但是却没有得到有用信息;

解决此问题:要为Publisher对象添加一个__unicode__()方法,他告诉python将对象以unicode方式显示,如下:

vim ~/HelloWorld/mysql_django/models.py

from django.db import models

class Publisher(models.Model):
     name = models.CharField(max_length=30)
     ......................
     website = models.URLField()
**      def __unicode__(self):
**       return self.name
class Author(models.Model):
     .........................
**    def __unicode__(self):
**       return u‘%s %s‘ % (self.first_name, self.last_name)**
class Book(models.Model):
     .........................
**    def __unicode__(self):
**       return self.title

============================================================================================

unicode对象 是能处理上百万不同类的字符串的python字符串。普通的python字符串是经过编码的,穿插调用的话就会出现常见的???等乱七八糟的字符,这就是编码的问题;而unicode对象没有编码,使用它可以不用考虑编码的问题。所以请确保每个模型都定义了__unicode__()方法。

关于unicode:http://www.joelonsoftware.com/articles/Unicode.html

再次进入shell解释器内,试验:>>> publisher_list

[<Publisher: Apress>, <Publisher: O‘Reilly>]

============================================================================================

1、数据查看、过滤操作:

>>> Publisher.objects.filter(name=‘Apress‘)
[<Publisher: Apress>]          #filter == where name=‘Apress‘
>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")
[<Publisher: Apress>]          #逗号转换成了 and
>>> Publisher.objects.filter(name__contains="press")
[<Publisher: Apress>]          #__contains  = where name LIKE ‘%press%‘;
>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>           #get()方法获取单个对象,filter()函数返回一个记录集(列表)

(icontains[大小写无关的LIKE]、startwith/endswith、range[BETWEEN])

2、数据排序操作:
>>> Publisher.objects.order_by("name")     
[<Publisher: Apress>, <Publisher: O‘Reilly>]     #按字母排序
>>> Publisher.objects.order_by("state_province", "address")
[<Publisher: Apress>, <Publisher: O‘Reilly>]     #第一个字段相同,按第二个排序
>>> Publisher.objects.order_by("-name")
[<Publisher: O‘Reilly>, <Publisher: Apress>]     #-号,表示逆向排序

vim ~/HelloWorld/mysql_django/models.py   

class Publisher(models.Model):
    def __unicode__(self):
      return self.name
**   class Meta:              
**     ordering = [‘name‘]  #Meta类,默认会以name字段进行排序

3、连锁查询:
>>> Publisher.objects.filter(country="U.S.A.").order_by("-name")
[<Publisher: O‘Reilly>, <Publisher: Apress>]  #检索country="U.S.A."降序排列
>>> Publisher.objects.order_by(‘name‘)[0:2]   #取数据的特定子集=offset 0 limit 2,查询语句也可以加
>>> Publisher.objects.order_by(‘name‘)[0]    #[0]=limit 1;不支持负索引[-1],但可用降序[0]实现
<Publisher: Apress>

4、增加更改操作:(name、save、id、update)

添加数据:>>> p3 = ....name=‘Apress‘ ...

获取数据:>>> p2 = Publisher.objects.get(name="Apress")

更改数据:>>> p2.name = ‘Apress Publishing‘

保存数据:>>> p2.save()    #他会update此id全部字段,不只是name字段;也有轻量级更改的方法。

看主键id:>>> p2.id      #我们可根据get到的数据查id,也可直接进数据库查

更改数据:>>> Publisher.objects.filter(id=1).update(name=‘Apress Publishing‘)

批量更改:>>> Publisher.objects.all().update(country=‘USA‘)    #返回数值即更改的条数

5、删除命令操作:

获取数据:>>> p = Publisher.objects.get(name="O‘Reilly")      #先得到数据再删除

删除数据:>>> p.delete()

直接删除:>>> Publisher.objects.filter(country=‘USA‘).delete()  #删除所有country=‘USA‘的

删除全部:>>> Publisher.objects.all().delete()            #不加all()方法删除不了

查看数据:>>> Publisher.objects.all()

当然,以上的操作都是直接在shell解释器中操作,我们也可以写到视图函数中,页面化查看。

-------------------------------------------------------------------------------------------------

时间: 2024-11-25 11:41:20

Django -- 模型(数据库层)的相关文章

Django模型-数据库操作

前言 前边记录的URLconf和Django模板全都是介绍页面展示的东西,也就是表现层的内容.由于Python先天具备简单而强大的数据库查询执行方法,Django 非常适合开发数据库驱动网站. 这篇开始,进入到了Django模型,也就是数据库操作. 自带 Sqlite3 数据库查询方式 为了简单,使用Python自带的Sqlite3数据库进行实例说明. 先看一个传统的数据库操作示例: 1 from django.shortcuts import render 2 import sqlite3 3

4Python全栈之路系列之Django模型

Python全栈之路系列之Django模型 MTV开发模式 把数据存取逻辑.业务逻辑和表现逻辑组合在一起的概念有时被称为软件架构的Model-View-Controller(MVC)模式.在这个模式中,Model代表数据存取层,View代表的是系统中选择显示什么和怎么显示的部分,Controller指的是系统中根据用户输入并视需要访问模型,以决定使用哪个视图的那部分. Django紧紧地遵循这种MVC模式,可以称得上是一种MVC框架. 以下是Django中M.V和C各自的含义: **M**: 数

一 Django模型层简介

模型 django提供了一个强大的orm(关系映射模型)系统. 模型包含了你要在数据库中创建的字段信息及对数据表的一些操作 使用模型 定义好模型后,要告诉django使用这些模型,你要做的就是在配置文件中的INSTALLED_APPS中添加模型所在的应用名称 字段类型 模型中的每个字段都是Field类相应的实例,django根据Field类型来确定以下信息: 列类型,告知数据库要存储那种数据 渲染表单时使用的默认HTML widget 验证,被用在admin和表单中 通用字段参数(常用) nul

Django模型层(1)

ORM简介: MVC或者MTV框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动 ORM是"对象-关系-映射"的简称. 单表操作 创建模型: 创建名为book的app,在book下的model.py中创建模型 from django.db import models # Create your models here.

Django基础五之django模型层(一)单表操作

目录 一 ORM简介 二 单表操作 一.创建表 创建模型 2 更多字段和参数 3 settings配置 4.自定义字段(了解) 二.添加表纪录 方式1 方式2(用的多) 方式3:批量插入 三.查询表纪录 查询API(都是重点) 基于双下划线的模糊查询 四.删除表纪录 五.修改表纪录 三 章节作业 1 图书管理系统 2 查询操作练习 四 xxx 本节目录 一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,

Django模型层之单表操作

Django模型层之单表操作 一 .ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软件,例如mysql.oracle.Microsoft SQL Server等. 如果应用程序需要操作数据(比如将用户注册信息永久存放起来),那么我们需要在应用程序中编写原生sql语句,然后使用pymysql模块远程操作mysql数据库,详见图一^①^ 但是直接编写原生sql语句会存在两方面的问题,严

Django模型层之更多操作

Django模型层之更多操作 一 .ORM字段 1.1 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型,范围在-2147483648 to 2147483647. CharField 字符类型,必须提供max_length参数, max_length表示字符长度. DateField 日期字段,日期格式 YYYY-MM-DD,相当于Python中的d

03 Django模型层: 常用(非常用)字段和参数

Django模型层: 常用(非常用)字段和参数 1 ORM字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型,范围在 -2147483648 to 2147483647. CharField 字符类型,必须提供max_length参数, max_length表示字符长度. DateField 日期字段,日期格式? YYYY-MM-DD,相当于Python中的

Django基础之模型(models)层

目录 Django基础之模型(models)层 一 ORM简介 二.单表查询 Queryset队像和mployee对象 神奇的双下划线的模糊查询 聚合查询 分组查询 F与Q查询 F查询: Q查询 Q查询进阶 查询优化(面试) only与defer select_related与prefetch_related Django ORM中的事务操作 补充知识: Django基础之模型(models)层 Django测试环境搭建:拷贝manage.py中的行代码放到tests.py文件中导入模块 imp