Django model 层之ModelsMysql数据库小结

by:授客 QQ1033553122

测试环境:

Python版本:python-3.4.0.amd64

下载地址:https://www.python.org/downloads/release/python-340/

Win7 64位

 

Django  1.11.4

下载地址:https://www.djangoproject.com/download/

MySQL数据库为例,假设项目目录结构如下:

mysite/

myapp/

__init__.py

admin.py

apps.py

migrations/

__init__.py

models.py

tests.py

views.py

    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

配置数据库信息

打开项目根目录下,与项目同名的目录,编辑settings.py(例中mysite/mysite/settings.py文件),

找到以下代码
DATABASES = {
'default': {
……略
}
}
 
修改为以下内容:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testdb',
        'USER': 'testacc',
        'PASSWORD': 'test1234',
        'HOST': '192.168.1.102',
        'PORT': '3306',
        'OPTION':{
            'init_command': 'SET default_storage_engine=INNODB'
        }
    }
}

说明:

ENGINE:默认为空。可选值:

'django.db.backends.postgresql'

'django.db.backends.mysql'

'django.db.backends.sqlite3'

'django.db.backends.oracle'

NAME:数据库名字。

如果使用SQLite,数据库文件将存放在电脑上,这种情况下,NAME应该为绝对路径,包含数据库文件的文件名。默认值如下,把数据库文件存放在项目根目录下。

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.sqlite3',

'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

}

}

如果不使用SQLite,需要设置额外参数如USER, PASSWORDHOST, PORT

另外,确保提供的USER具备“create database”权限。

USER: 数据库用户名,默认为''

PASSWORD:连接数据库用户密码,默认为''

HOST: 数据库服务器主机地址,默认为'',代表localhost。支持tcp socket除外的其它socket连接方式,更多详情请查看官方文档。

PORT:数据库访问端口,默认为'',代表默认端口。

AUTOCOMMIT: 自动提交事务。默认为True。设置为False,则禁用Django 事务管理,采用自己实现的事务管理。

更多选项设置,请参考官方文档。

参考链接:

https://docs.djangoproject.com/en/1.11/ref/settings/#databases

建立表

编辑应用目录下的models.py文件(例中为 mysite/myapp/models.py)

from django.db import models
 
# Create your models here.
class Person(models.Model):
   first_name = models.CharField(max_length=30)
   last_name = models.CharField(max_length=30)

新增以上带背景色代码

first_name和last_name为model的field。每个field映射到一个数据库列。

以上Person model将创建如下表:

CREATE TABLE myapp_person (

"id" serial NOT NULL PRIMARY KEY,

"first_name" varchar(30) NOT NULL,

"last_name" varchar(30) NOT NULL);

注意:

1、如上,表名命名方式为应用名称_转为小写的model名称,我们可以通过Meta属性实现表名自定义,如下:

CREATE TABLE myapp_person (

"id" serial NOT NULL PRIMARY KEY,

"first_name" varchar(30) NOT NULL,

"last_name" varchar(30) NOT NULL);

class Meta:

db_table = 'tb_person'#数据库中创建的表名称即为 tb_person

verbose_name = '用户表'#表名称 #在admin站点中显示的名称

verbose_name_plural = verbose_name#显示的复数名称

2、自动为数据库增加 id 自增主键列。因为,默认的,Django为每个模块设置一个field:

id = models.AutoField(primary_key=True)

如果想自己指定一个自定义的主键列,则必须按上述设置,显示指定字段名称。总之,不管是默认设置还是显示设置,必须有一个自增主键列。

参考链接:

https://docs.djangoproject.com/en/1.11/topics/db/models/#automatic-primary-key-fields

 
class Book(models.Model):
    book_name = models.CharField(max_length=30)
    borrower = models.ForeignKey(Person, to_field='id', on_delete=models.CASCADE)
 
说明:mysql中,生成的外键列名称,会自动命名为:field_id,如上borrower field对应的mysql列为borrower_id
 
class Musician(models.Model):
    auto_id = models.IntegerField(primary_key=True)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)
    last_update = models.DateField(auto_now=True, auto_now_add=True)
 
class Album(models.Model):
    artist = models.ForeignKey(Musician, to_field='auto_id', on_delete=models.PROTECT)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

Field 类型

AutoField

IntegerField,根据可获取的ID列值,自增

参数:verbose_name,个人推断,所有Field类型应该都有该参数,用于设置字段名称

BigAutoField

64位整型,类似AutoField,不同之处在于它可接收更大范围的数值:1 到9223372036854775807.

Django 1.10新增。

BigIntegerField

64位整型,类似IntegerField。不同之处在于它可接纳更大范围的数值:-9223372036854775808 到9223372036854775807。该field对应的默认组建:TextInput

BinaryField

用于存储原始二进制数据,仅支持字节。

BooleanField

true/false field.该field对应的默认表单组件:CheckboxInput。

如果需要接收null值,则使用NullBooleanField替代BooleanField。

如果未定义Field.default,那么BooleanField field默认值为None。

CharField

字符串类型。用于存储一定范围大小的字符串。针对大量文本,使用TextField。该field的默认组建为:TextInput

CharField有个额外的必填参数。CharField.max_length。设置可接纳的最大字符数。

DateField

日期类型。代表Python datetime.date实例。

class DateField(auto_now=False, auto_now_add=False, **options)[source]

可选参数:

DateField.auto_now

每次存储对象(仅针对调用save方法)时,自动设置该field的值为当前日期

注意:实践发现,调用Module_name.objects.Create()方法创建对象,auto_now()也起作用

 

DateField.auto_now_add

第一次创建对象时,自动设置field值为当前日期,所以,即便显示为该字段提供了值,也会自动忽视显示设定的值。

对于DateField:default=date.today - datetime.date.today()

对于DateTimeField: default=timezone.now - django.utils.timezone.now()

该field对应的默认表单组件为:TextInput。

注意:auto_now_add和auto_now两个参数不能同时使用。

TimeField

以python datetime.time实例表示的时间

可选参数:

DateField.auto_now

每次存储对象(仅针对调用save方法)时,自动设置该field的值为当前日期

 

DateField.auto_now_add

第一次创建对象时,自动设置field值为当前日期,所以,即便显示为该字段提供了值,也会自动忽视显示设定的值。

对于DateField:default=date.today - datetime.date.today()

对于DateTimeField: default=timezone.now - django.utils.timezone.now()

该field对应的默认表单组件为:TextInput。

DateTimeField

以python datetime.datetime实例表示的日期时间。

可选参数:

DateField.auto_now

每次存储对象(仅针对调用save方法)时,自动设置该field的值为当前日期时间

 

DateField.auto_now_add

第一次创建对象时,自动设置field值为当前日期时间,所以,即便显示为该字段提供了值,也会自动忽视显示

该field对应的默认表单组件为:TextInput。

DateTimeField字段的值,如果要保存为当前时间,可以通过timezone.now()快速获取当前时间进行赋值

>>> from django.utils import timezone

>>> update_time = timezone.now()

>>>user = User(username='test1', password='passwd123', email='email@163.com', update_time=update_time)

>>> user.save()

DecimalField

用Python Decimal实例表示的固定精度的数字。有两个必填参数:

DecimalField.max_digits

表示允许的最大值。必须大于等于decimal_spaces

 

DecimalField.decimal_places

设置精度位数。

比如field存储最大值不超过999,2位小数,设置如下:

models.DecimalField(..., max_digits=5, decimal_places=2)

该field对应的默认表单组件:当设置localize为False,则对应NumberInput,否则TextInput。

DurationField

存储以python timedelat表示的一段时间

EmailField

一个CharField,校验值是否是合法的email地址。使用EmailValidator校验输入值。

FileField

file-upload field。

注意:主键列不支持该类型。

更多详情参考官方文档。

FilePathField

一个CharField,可取值限制于系统上某个目录中的文件名

更多详情参考官方文档。

FloatField

python float实例表示的浮点数。

该field对应的默认表单组件:当设置localize为False,则对应NumberInput,否则TextInput。

ImageField

继承了FileField的所有属性和方法。校验上载对象是否是合法的图片。

更多详情参考官方文档。

IntegerField

整数。值从-2147483648 到2147483647,支持所有数据库。

该field对应的默认表单组件:当设置localize为False,则对应NumberInput,否则TextInput。

GenericIPAddressField

字符串格式(例如:192.0.2.30 or 2a02:42fe::4)表达的IPv4或IPv6地址,,针对IPv6,所有字符都会转为小写。

该field对应的默认表单组件:TextInput。

更多详情参考官方文档。

NullBooleanField

类似BooleanField,不同之处在于运行NULL值。等同BooleanField(...,null=True)。

该field对应的默认表单组件为NullBooleanSelect。

PositiveIntegerField

类似IntergerField,不同在于只接受正数,或者0.可取值范围:0 到2147483647

PositiveSmallIntegerField

类似PositiveIntegerField,可取值范围: 0 到 32767

SlugField

更多详情参考官方文档。

SmallIntegerField

类似IntegerField,取值范围:-32768 到 32767

TextField

大文本field。如果指定max_length属性,将作用于组件,但是不会是在数据库、model层起作用(If you specify a max_length attribute, it will be reflected in the Textarea widget of the auto-generated form field. However it is not enforced at the model or database level)。

该field对应的默认表单组件为:Textarea。

URLField

针对URL的CharField。可选参数:max_length,设置最大长度。默认200.

field对应的默认表单组件为:TextInput

UUIDField

存储全球唯一标识(universally unique identifier)。使用Python的UUID类。

对于主键AutoField来说,UUIDFeild是个很好的选择。但是数据库不会生成UUID,所以推荐使用default,如下:

import uuidfrom django.db import models

 

class MyUUIDModel(models.Model):

id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

# other fields

参考链接:

https://docs.djangoproject.com/en/1.11/ref/models/fields/#model-field-types

常用Field option

null

如果设置null=True,保存数据到数据库时,把“空值”存储为NULL。默认null=False。

blank

如果设置blank=True, 允许Field值为空,字符型字段CharField和TextField是用空字符串来存储空值的。默认False

注意:

blank 是针对表单的,如果 blank=True,表示你的表单填写该字段的时候可以不填。

null 是针对数据库而言,如果 null=True, 表示数据库的该字段可以为空,那么在新建一个model对象的时候是不会报错的!!

choice

一个由多个2元组,组成的可迭代对象(如tuple、list)。

如果设置了该选项值,那么默认的表单组件将变为一个select box,而不是标准是text field,且将被限制从给定choice中选择choice。

choice 列表,形如以下:

YEAR_IN_SCHOOL_CHOICES = (

('FR', 'Freshman'),

('SO', 'Sophomore'),

('JR', 'Junior'),

('SR', 'Senior'),

('GR', 'Graduate'),)

每个元组中第一个元素,将被存储在数据库中,第二个元素用于默认表单组件展示

例:

from django.db import models

class Person(models.Model):

SHIRT_SIZES = (

('S', 'Small'),

('M', 'Medium'),

('L', 'Large'),

)

name = models.CharField(max_length=60)

shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

>>> p = Person(name="Fred Flintstone", shirt_size="L")

>>> p.save()

>>> p.shirt_size

'L'

>>> p.get_shirt_size_display()

'Large'

default

设置field的默认值。可以是可调用对象,也可以是某个值。如果是可调用对象,每次创建对象,都会被调用

help_text

同表单组件一起展示的帮助说明

primary_key

如果设置primary_key=True,那么该field将是model的主键

主键Field只读。如果修改某个已存在对象,主键列的值,并保存该对象,会在旧对象的基础上,重新构建一个对象。

例:

from django.db import models

class Fruit(models.Model):

name = models.CharField(max_length=100, primary_key=True)

>>> fruit = Fruit.objects.create(name='Apple')

>>> fruit.name = 'Pear'

>>> fruit.save()

>>> Fruit.objects.values_list('name', flat=True)

<QuerySet ['Apple', 'Pear']>

unique

如果设置unique=True,则该field不允许有重复值。

参考链接:

https://docs.djangoproject.com/en/1.11/topics/db/models/#field-options

关联关系

外键关联

假设artist model对应mysql表为 myapp_album, Musician model对应的mysql表为Musician表为myapp_musician,则以下field定义,会使两个mysql表建立外键关联关系。myapp_album.artist列引用mapp_musician.auto_id字段的值,即mapp_musician.auto_id为myapp_album表的外键。

 

class Album(models.Model):

artist = models.ForeignKey(Musician, to_field='auto_id', on_delete=models.PROTECT)

为方便理解,如上,暂时把Album、Musician Model称之为表,对应Model对象称之为表记录,存在外键关联的两个表,分别称之为参照表(如上的Album),被参照表(如上的Musician)

假设Musician代码位于 Album代码之前,那么执行以上代码时将报错,因为那会还没有定义Musician,如果不调整代码顺序,即定义表的先后顺序,那怎么办呢?

解决方案:把关联表写成字符串形式,如下:

class Album(models.Model):

    artist = models.ForeignKey('Musician', to_field='auto_id', on_delete=models.PROTECT)

自身关联

假设有表appame_resource,结构如下,其中parent的值如果不为NULL则为某条记录的id值

id name parent

1  xxx1  NULL

2  xxx2   1

这种情况则需要进行自身表关联设计,model设计如下:

class Resource(models.Model):

id = models.AutoField(primary_key=True, verbose_name='资源ID')

parent = models.ForeignKey('self', to_field='id', null=True, blank=True, on_delete=models.CASCADE)

name = models.CharField(max_length=20, verbose_name='资源名称')

null参数值说明:该值默认为False,设置为True则表示允许字段为null,空值将被存储为NULL

blank参数值说明:该值默认为False,设置为True则表示允许字段为空值

on_delete参数值说明:

2.0版本,该参数值必填,更早之前的版本则默认为CASCADE。

可选值:

CASCADE

级联删除。模拟sql约束 ON DELETE CASCADE。删除被参照表的某条表记录,同时级联删除参照表中,同待删除记录存在外键关联关系的记录。

PROTECT

删除被参照表中的某条表记录,如果参照表中,存在与该记录有外键关系的记录,则不让删除。

SET_NULL

删除被参照表的某条表记录,设置参照表中,同待删除记录存在外键关联的记录的外键列值为null。当且仅当设置了null=True选项时可用。

SET_DEFAULT

删除被参照表的某条表记录,设置参照表中,同待删除记录存在外键关联的记录的外键列值为默认值。必须为外键列设置默认值。

SET()

删除被参照表的某条表记录,设置参照表中,同待删除记录存在外键关联关系的记录的外键列值为传递给SET()的参数值,如果传递给SET()的参数值是可调用对象,则设置为调用可调用对象获取的结果。

官方例子:

from django.conf import settings

from django.contrib.auth import get_user_model

from django.db import models

def get_sentinel_user():

return get_user_model().objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):

user = models.ForeignKey(

settings.AUTH_USER_MODEL,

on_delete=models.SET(get_sentinel_user),

)

DO_NOTHING

删除被参照表的某条表记录,不对参照表中同待删除记录存在外键关联的记录做任何处理。

参考链接:

https://docs.djangoproject.com/en/1.11/ref/models/fields/#foreignkey

参考链接:

https://docs.djangoproject.com/en/1.11/topics/db/models/#relationships

联合主键

例子:如下,希望project_id和user_id字段组合唯一

class APIProjectFacorites(models.Model):

id = models.AutoField(primary_key=True, verbose_name='自增id')

project_id = models.CharField(blank=True, null=True, max_length=300, verbose_name='项目id')

user_id = models.CharField(blank=True, null=True, max_length=15, verbose_name='用户id')

class Meta:

db_table = 'tb_api_project_facorities'

        unique_together = ("project_id", "user_id")

verbose_name = 'API项目收藏表'

        verbose_name_plural = verbose_name

组织models

1、如果manager.py 启动app,会创建包含一个models.py的文件。如果有许多model,可以按单个文件的方式组织model。新建models包来管理,具体方法如下:

然后移除models.py,并创建一个myapp/models目录,在该目录下新建__init__.py文件,用于存放models。

例:

假设在models目录下存在models文件,organic.py 和synthetic.py,编辑myapp/models/__init__.py,新增以下内容:

from .organic import Person

from .synthetic import Robot

参考链接:

https://docs.djangoproject.com/en/1.11/topics/db/models/

https://docs.djangoproject.com/en/1.11/

Django model 层之Models与Mysql数据库小结的更多相关文章

  1. Python+Django+SAE系列教程12-----配置MySQL数据库

    由于SAE上支持的是Mysql,首先我们要在本地配置一个Mysql的环境 ,我在网上找到MySQL-python-1.2.4b4.win32-py2.7.exe,并双击 安装 选择典型安装 安装结束后 ...

  2. Django模型层(models.py)之模型创建

    Django数据库操作是十分重要的内容,这两天简单学习了数据库的操作,这里做个总结. 1.ORM简介 简单的来说,ORM就是对象-关系-映射.它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖 ...

  3. python web开发——django学习(一)第一个连接mysql数据库django网站运行成功

    1.新建一个项目 2.新建一些文件夹方便管理 3.新建一个项目叫message  4.连接数据库 python web开发Django连接mysql 5.在数据库里自动生成django的表  6.运行 ...

  4. Django中manger/QuerySet类与mysql数据库的查询

    Django中的单表操作 1.精确查询 #查询的结果返回是容器Query Set的函数(Query Set模型类)​# 1. all()   查询的所有的符合条件的结果,支持正向索引,支持索引切片,不 ...

  5. 在django中使用orm来操作MySQL数据库的建表,增删改

    多张表之间的三种关系:一对一,一对多,多对多 创建表 一对一 xx = models.OneToOneField(to='表明',to_field='字段名',on_delete=models.CAS ...

  6. Mysql数据库小结

    1. 基础概念 1.1 数据 描述事物的符号记录称为数据,描述事物的符号既可以是数字,也可以是文字.图片,图像.声音.语言等,数据由多种表现形式,它们都可以经过数字化后存入计算机 在计算机中描述一个事 ...

  7. django中mysql数据库设置错误解决方法

    刚在django中settings.py进行设置mysql数据库. 当进行执行python manage.py shell命令时会报以下错误: 只需要在settings.py中 DATABASES = ...

  8. Django model总结(上)

    Django model是django框架中处于比较核心的一个部位,准备分三个博客从不同的方面分别进行阐述,本文为<上篇>,主要对[a]Model的基本流程,比如它的创建,迁移等:默认行为 ...

  9. Mysql数据库的压力

    rationalError: (2006, 'MySQL server has gone away') 2017年10月10日 20:04:43 阅读数:377 问题描述 使用django+celer ...

  10. MySQL数据库分布式事务XA优缺点与改进方案

    1 MySQL 外部XA分析 1.1 作用分析 MySQL数据库外部XA可以用在分布式数据库代理层,实现对MySQL数据库的分布式事务支持,例如开源的代理工具:ameoba[4],网易的DDB,淘宝的 ...

随机推荐

  1. Android 13 - Media框架(21)- ACodec(三)

    关注公众号免费阅读全文,进入音视频开发技术分享群! 这一节我们一起来了解 ACodec 是如何通过 configureCodec 方法配置 OMX 组件的,因为 configureCodec 代码比较 ...

  2. WPF开发快速入门【3】WPF的基本特性(附加属性)

    概述 本文描述WPF的附加属性.对于使用MVVM框架的项目,附加属性是非常重要的一个特性. 在MVVM框架下,ViewModel的代码通过控件的依赖属性来控制控件的,例如: //ViewModel p ...

  3. C# 配置文件增加自定义节点

    话不多说直接开撸! 首先创建一个Config的文件夹然后新增一个后缀名为.config的文件 配置文件的代码如下: <?xml version="1.0" encoding= ...

  4. kettle从入门到精通 第五十五课 ETL之kettle Excel输入

    1. Excel输入,Microsoft Excel输入步骤的作用是从Microsoft Excel中读取数据,如下图所示: 1)Excel输入步骤从文件D:\data\测试数据.xlsx读取数据. ...

  5. IDEA的安装、激活(到25年2月)&汉化

    1,在官网下载IDEA软件,官网 2,下载之后,双击安装包,然后一直点击next即可. (中间可以按照自己的要求设置安装目录) 3,快捷方式和java打钩 4,点击install即可进行安装,时间有一 ...

  6. Linux扩展篇-shell编程(三)-shell运算符

    基本语法: 格式一 expr +. -. \*./. %(加.减.乘.除.求余) 格式二 "$((运算式))"或者"$[运算式]" 基本运算符 Shell 和其 ...

  7. FlashDuty Changelog 2023-12-18 | 值班管理、服务日历、自定义操作和邮件集成

    FlashDuty:一站式告警响应平台,前往此地址免费体验! 值班管理 UI 交互优化 [个人日程]从头像下拉菜单调整到值班列表页面,快速查看个人值班日程 [值班列表]支持原地预览最近一周值班情况,包 ...

  8. 🌟 简单理解 React 的 createContext 和 Provider 🚀

    在 React 应用中,我们经常需要在组件之间共享状态和数据.而 React 的 createContext 和 Provider 就是为了解决这个问题而诞生的. createContext:创建自定 ...

  9. java中判断一个String字符串或字符数组中包含某个字段

    /** * 判断String字符串中包含某个字段 * @param oriStr 原始字符串 * @return */ private static boolean findString(String ...

  10. PowerBI_一分钟了解POWERBI计算组_基础运用篇(一)

    在第一篇计算组的文章中,给大家介绍了,POWERBI的计算组功能的基本概念和作用. 本文,旨在通过简单案例,介绍计算组功能的具体应用场景. 没有看过第一篇的同学,可以先简单过一下第一篇,补齐一下概念和 ...