数据类型以及数据关系

2018-04-10  本文已影响0人  流蓝浅

Model

ORM简介

 MVC 框架中包括一个重要的部分,就是 ORM,它实现了数据模型与数据库的解耦
 即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库
 ORM 即Object-Relational Mapping是“对象-关系-映射”的简称,主要任务是:
o 根据对象的类型生成表结构
o 将对象、列表的操作,转换为 sql 语句
o 将 sql 查询到的结果转换为对象、列表
Django 中的模型包含存储数据的字段和约束,对应着数据库中唯一的表

ORM分为两种:

 DB First 数据库里先创建数据库表结构,根据表结构生成类,根据类操作数据库
 Code First 先写代码,执行代码创建数据库表结构
主流的orm都是code first。django 的orm也是code first,所以学的时候,本质就分
为两块:
 根据类自动创建数据库表
 根据类对数据库表中的数据进行各种操作
优点:
摆脱复杂的SQL操作,适应快速开发;
让数据结构变得简洁;
数据库迁移成本更低
注意:数据库django不能创建,需要自己提前创建

开发流程
  1. 在 models.py 中定义模型类,要求继承自 models.Model
  2. 把应用加入settings.py 文件的installed_app 项
  3. 生成迁移文件
  4. 执行迁移生成表
  5. 使用模型类进行crud 操作
    定义模型
    在模型中定义属性,会生成表中的字段
    模型类要求继承自 models.Model
    属性命名限制
     不能是python 的保留关键字
     由于django 的查询方式,不允许使用连续的下划线
    定义属性
  6. 导入from django.db import models
  7. 通过models.Field 创建字段类型的对象,赋值给属性
     对于重要数据都做逻辑删除,不做物理删除,实现方法是定义 isDelete 属性,类型为
    BooleanField,默认值为 False
    btitle = models.CharField(max_length=20)
字段类型

 AutoField:一个根据实际 ID自动增长的 IntegerField
django 会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置
某属性为主键列后,则 django 不会再生成默认的主键列
id = models.AutoField(primary_key=True)

 BooleanField:true/false 字段,此字段的默认表单控制是 CheckboxInput
 NullBooleanField:支持 null、true、false 三种值
 CharField(max_length=字符长度):字符串,默认的表单样式是 TextInput
 TextField:大文本字段,一般超过 4000 使用,默认的表单控件是 Textarea
 IntegerField:整数
 DecimalField(max_digits=None, decimal_places=None):使用python 的 Decimal
实例表示的十进制浮点数
 DecimalField.max_digits:位数总数
 DecimalField.decimal_places:小数点后的数字位数
 FloatField:用Python 的 float 实例来表示的浮点数
 DateField[auto_now=False, auto_now_add=False]):使用 Python 的 datetime.date

实例表示的日期

 参数DateField.auto_now:每次保存对象时,自动设置该字段为当前时间,用
于"最后一次修改"的时间戳,它总是使用当前日期,默认为 false
 参数DateField.auto_now_add:当对象第一次被创建时自动设置当前时间,用
于创建的时间戳,它总是使用当前日期,默认为 false
 auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任
何组合将会发生错误的结果
 TimeField:使用 Python 的 datetime.time 实例表示的时间,参数同 DateField

 DateTimeField:使用 Python 的 datetime.datetime 实例表示的日期和时间,参数同
DateField
 FileField:一个上传文件的字段
 ImageField:继承了 FileField 的所有属性和方法,但对上传的对象进行校验,确保它是
个有效的image
 上传路径设置:
字段选项STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static')
]
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")

 通过字段选项,可以实现对字段的约束
 在字段对象时通过关键字参数指定
 null:如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False
 blank:如果为True,则该字段允许为空白,默认值是 False
 对比:null是数据库范畴的概念,blank 是表单验证证范畴的
 如果一个字段设置为blank=True,表单验证时允许输入一个空值。而blank=False,
则该项必需输入数据。
 db_column:字段的名称,如果未指定,则使用属性的名称
 db_index:若值为 True, 则在表中会为此字段创建索引
 default:默认值
 primary_key:若为 True, 则该字段会成为模型的主键字段
 unique:如果为True,该字段在表中必须有唯一的值
 help_text:会在form 表单控件中显示 help 文本

关系

 关系的类型包括
o ForeignKey:一对多,将字段定义在多的端中
o ManyToManyField:多对多,将字段定义在两端中
o OneToOneField:一对一,将字段定义在任意一端中

 用一访问多:对象.模型类小写_set
bookinfo.heroinfo_set
 django 默认每个主表的对象都有一个是外键的属性,可以通过它来查询到子表的信息。

 这个属性的名称默认是以子表的名称小写加上_set来表示
 默认返回的是一个querydict对象
 自定义名称:person = models.ForeignKey(Person, related_name='person_set')
 hBook = models.ForeignKey('BookInfo', \
related_name='person_set',\
on_delete=models.CASCADE)
 用一访问一:对象.模型类小写
heroinfo.bookinfo
 访问id:对象.属性_id
heroinfo.book_id

django 2.0,外键(ForeignKey)和一对一(OneToOneField),必须要写on_delete参数
否则会报异常:
TypeError: init() missing 1 required positional argument: 'on_delete'
on_delete参数的各个值的含义:
on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE, # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING, # 删除关联数据,什么也不做
on_delete=models.PROTECT, # 删除关联数据,引发错误ProtectedError
on_delete=models.SET_NULL, # 删除关联数据,与之关联的值设置为null(前提FK字段
需要设置为可空,一对一同理)
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK
字段需要设置默认值,一对一同理)

一对一

from django.db import models

# Create your models here.
#帐户
class Account(models.Model):
    username = models.CharField(max_length=20,null=True)
    password = models.CharField(max_length=20)
    register_date = models.DateField(auto_now_add=True)


#联系人
class Concat(models.Model):
    account = models.OneToOneField(Account,on_delete=models.CASCADE)
    address = models.CharField(max_length=30)
    mobile = models.CharField(max_length=11)
    
#黑窗口 操作
(envtest44) D:\test\vritualenv\envtest44\demo02>python manage.py shell
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from one_to_one.models import Account,Concat
>>> from * import datetime
  File "<console>", line 1
    from * import datetime
         ^
SyntaxError: invalid syntax
>>> from datetime import *
>>> a = Account()
>>> a.username='Tom'
>>> a.password='123'
>>> a.save()
>>> c = Concat()
>>> c.account = a
>>> c.address = 'zz'
>>> c.save()
>>> print(c.account)
Account object (1)
>>> print(c.account.username)
Tom
>>> print(a.concat)
Concat object (1)
>>> print(a.concat.address)
zz
>>> exit()


多对多

from django.db import models

# Create your models here.


class Host(models.Model):
    id = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=20)


class Application(models.Model):
    name = models.CharField(max_length=20)
    rat = models.ManyToManyField(to="Host")

# 黑窗口中检测
envtest44) D:\test\vritualenv\envtest44\demo02>python manage.py shell
Python 3.5.3 (v3.5.3:1880cb95a742, Jan 16 2017, 16:02:32) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from many_to_many.models import Host,Application
>>> a = Application(1,'qq')
>>> a.save()
>>> h1 = Host(hostname='host1')
>>> h1.save()
>>> h2 = Host(hostname='host2')
>>> h2.save()
>>> h3 = Host(hostname='host3')
>>> h3.save()
>>> a.rat.add(1)
>>> a.rat.add(2,3)
>>> a.rat.all()
<QuerySet [<Host: Host object (1)>, <Host: Host object (2)>, <Host: Host object (3)>]>
>>> h1.application_set.all()
<QuerySet [<Application: Application object (1)>]>
>>> a.rat.remove()
>>> a.rat.remove(1)
>>>
上一篇下一篇

猜你喜欢

热点阅读