Python Web框架篇:Django Model基础
model是关于你的数据的单一的,确定的信息来源。 它包含您正在存储的数据的基本字段和行为。Django通过抽象化的模型层(models)为你的网络应用提供对于数据的结构化处理和操作处理,数据库相关的代码一般写在 models.py 中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,使用数据库API对数据库进行增删改查的操作。
使用哪种数据库,只需要在settings.py中配置即可,如:
<1> sqlite: django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 , 引擎名称:django.db.backends.sqlite3
<2> mysql:引擎名称:django.db.backends.mysql
<3>如果想更改数据库:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'books', #你的数据库名称
'USER': 'root', #你的数据库用户名
'PASSWORD': '', #你的数据库密码
'HOST': '', #你的数据库主机,留空默认为localhost
'PORT': '', #你的数据库端口
} }
注意事项:
NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建
USER和PASSWORD分别是数据库的用户名和密码。
设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。
然后,启动项目,会报错:no module named MySQLdb
这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到项目名文件下的__init__,在里面写入:
import pymysql
pymysql.install_as_MySQLdb()
Model 字段
AutoField 根据实际ID自动增长的IntegerField . 你通常不需要直接使用;
如果不指定,一个主键字段将自动添加到你创建的
BigIntegerField 一个64位整数, 类似于一个 IntegerField 这个字段默认的表单组件是一个TextInput. IntegerField([**options])
一个整数。在Django所支持的所有数据库中,从 -2147483648 到 2147483647 范围内的值是合法的。默认的表单输入工具是TextInput. BinaryField 用来存储原始二进制码的Field. 只支持bytes 赋值,注意这个Field只有很有限的功能。
例如,不大可能在一个BinaryField 值的数据上进行查询
BooleanField true/false 字段。默认表单挂件是一个CheckboxInput.
如果你需要设置null 值,则使用NullBooleanField 来代替BooleanField。
如果Field.default没有指定的话, BooleanField 的默认值是 None。
CharField 一个用来存储从小到很大各种长度的字符串的地方。
如果是巨大的文本类型, 可以用 TextField.
这个字段默认的表单样式是 TextInput.
CharField必须接收一个额外的参数:
CharField.max_length¶:字段的最大字符长度.max_length将在数据库层和Django表单验证中起作用, 用来限定字段的长度.
DateField 这是一个使用Python的datetime.date实例表示的日期. 有几个额外的设置参数: DateField.auto_now¶ 每次保存对象时,自动设置该字段为当前时间。
用于"最后一次修改"的时间戳。注意,它总是使用当前日期;它不只是一个默认值,你可以覆盖。 DateField.auto_now_add¶ 当对象第一次被创建时自动设置当前时间。用于创建时间的时间戳.
它总是使用当前日期;和你可以覆盖的那种默认值不一样。 该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件,
和一个“Today"的快捷按钮.包含了一个额外的invalid_date错误消息键. DateTimeField(DateField) - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field) - 时间格式 HH:MM[:ss[.uuuuuu]] DurationField(Field)用作存储一段时间的字段类型 - 类似Python中的timedelta.
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 DecimalField(max_digits=None, decimal_places=None[, **options]) 表示十进制浮点数 EmailField([max_length=254, **options])一个 CharField 用来检查输入的email地址是否合法。它使用 EmailValidator 来验证输入合法性。 FileField([upload_to=None, max_length=100)一个上传文件的字段。
FileField字段不支持primary_key 和unique参数,如果使用会生成 TypeError错误 FilePathField(path=None[, match=None, recursive=False, max_length=100])
一个 CharField ,内容只限于文件系统内特定目录下的文件名。有三个参数, 其中第一个是 必需的: FloatField([**options])用Python的一个float 实例来表示一个浮点数. ImageField([upload_to=None, height_field=None, width_field=None, max_length=100, **options])¶
继承了 FileField的所有属性和方法, 但还对上传的对象进行校验,确保它是个有效的image. TextField([**options])大文本字段。该模型默认的表单组件是Textarea。 TimeField([auto_now=False, auto_now_add=False, **options])¶
时间字段,和Python中 datetime.time 一样。接受与DateField相同的自动填充选项。
表单默认为 TextInput.输入框。 URLField([max_length=200, **options])一个CharField 类型的URL此字段的默认表单widget为TextInput。 UUIDField([**options])一个用来存储UUID的字段。使用Python的UUID类。
当使用PostgreSQL数据库时,该字段类型对应的数据库中的数据类型是uuid
字段选项(Field options)——参数
Field.null 如果为True,Django将在数据库中将空值存储为NULL。默认值是 False。 Field.blank 如果为True,则该字段允许为空白。 默认值是 False。 Field.choices 它是一个可迭代的结构(比如,列表或是元组),
由可迭代的二元组组成(比如[(A, B), (A, B) ...]),用来给这个字段提供选择项。
如果设置了 choices ,默认表格样式就会显示选择框,而不是标准的文本框,而且这个选择框的选项就是 choices 中的元组。 Field.db_column 数据库中用来表示该字段的名称。如果未指定,那么Django将会使用Field名作为字段名. Field.db_index 若值为 True, 则 django-admin sqlindexes 将会为此字段输出 CREATE INDEX 语句。 Field.error_messages 能够让你重写默认抛出的错误信息。通过指定 key 来确认你要重写的错误信息。 Field.primary_key若为 True, 则该字段会成为模型的主键字段。
如果你没有在模型的任何字段上指定 primary_key=True, Django会自动添加一个 AutoField 字段来充当主键。 Field.unique 如果为 True, 这个字段在表中必须有唯一值. Field.unique_for_month 类似unique_for_date,只是要求字段对于月份是唯一的。 验证器
Field.validators 该字段将要运行的一个Validator 的列表。
元信息Meta——使用内部的class Meta 定义模型的元数据
from django.db import models
class Ox(models.Model):
horn_length = models.IntegerField()
class Meta:
ordering = ["horn_length"]
verbose_name_plural = "oxen"
模型元数据是“任何不是字段的数据”,比如排序选项(ordering),数据表名(db_table)或者人类可读的单复数名称(verbose_name 和verbose_name_plural)。
在模型中添加class Meta是完全可选的,所有选项都不是必须的。
关系字段
关系数据库的威力体现在表之间的相互关联。
Django 提供了三种最常见的数据库关系:多对一(manyto-one),多对多(many-to-many),一对一(one-to-one)。
多对一关系
Django 使用 django.db.models.ForeignKey 定义多对一关系。和使用其它字段类型一样:在模型当中把它做为一个类属性包含进来。
ForeignKey 需要一个位置参数:与该模型关联的类。
limit_choices_to 当这个字段使用模型表单或者Admin 渲染时(默认情况下,查询集中的所有对象都可以使用),
为这个字段设置一个可用的选项。它可以是一个字典、一个Q 对象或者一个返回字典或Q对象的可调用对象。
Q(caption='root')
db_constraint=True # 是否在数据库中创建外键约束
parent_link=False # 在Admin中是否显示关联数据 related_name 这个名称用于让关联的对象反查到源对象。它还是related_query_name 的默认值(关联的模型进行反向过滤时使用的名称)。 related_query_name 这个名称用于目标模型的反向过滤。如果设置了related_name,则默认为它的值,否则默认值为模型的名称 to_field 关联到的关联对象的字段名称。默认地,Django 使用关联对象的主键。 db_constraint控制是否在数据库中为这个外键创建约束。默认值为True on_delete 当一个ForeignKey 引用的对象被删除时,Django 默认模拟SQL 的ON DELETE CASCADE 的约束行为,并且删除包含该ForeignKey的对象。这种行为可以通过设置on_delete 参数来改变。 CASCADE级联删除;默认值。 PROTECT抛出ProtectedError 以阻止被引用对象的删除,它是django.db.IntegrityError 的一个子类。 SET_NULL把ForeignKey 设置为null; null 参数为True 时才可以这样做。 SET_DEFAULT ForeignKey值设置成它的默认值;此时必须设置ForeignKey 的default 参数。 SET() 设置ForeignKey 为传递给SET() 的值,如果传递的是一个可调用对象,则为调用后的结果。
DO_NOTHING不采取任何动作。如果你的数据库后端强制引用完整性,它将引发一个IntegrityError ,除非你手动添加一个ON DELETE 约束给数据库自动
ManyToManyField一个多对多关联。
要求一个关键字参数:与该模型关联的类,与ForeignKey 的工作方式完全一样,包括递归关系 和惰性关系。
关联的对象可以通过字段的RelatedManager 添加、删除和创建。
如果源模型和目标不同,则生成以下字段:
id:关系的主键。
<containing_model>_id:声明ManyToManyField 字段的模型的id。
<other_model>_id:ManyToManyField 字段指向的模型的id。 如果ManyToManyField 的源模型和目标模型相同,则生成以下字段:
id:关系的主键。
from_<model>_id:源模型实例的id。
to_<model>_id:目标模型实例的id。
这个类可以让一个给定的模型像普通的模型那样查询与之相关联的记录。 to, # 要进行关联的表名
related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名') limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5} from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root') symmetrical=None,# 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
# 做如下操作时,不同的symmetrical会有不同的可选字段
models.BB.objects.filter(...) # 可选字段有:code, id, m1
class BB(models.Model): code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True) # 可选字段有: bb, code, id, m1
class BB(models.Model): code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False) through=None, # 自定义第三张表时,使用字段用于指定关系表
through_fields=None, # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
from django.db import models class Person(models.Model):
name = models.CharField(max_length=50) class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
) class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
inviter = models.ForeignKey(
Person,
on_delete=models.CASCADE,
related_name="membership_invites",
)
invite_reason = models.CharField(max_length=64) db_constraint=True, # 是否在数据库中创建外键约束
db_table=None, # 默认创建第三张表时,数据库中表的名称
OneToOneField
一对一关联关系。概念上讲,这个字段很像是ForeignKey 设置了unique=True,不同的是它会直接返回关系另一边的单个对象。
它最主要的用途是作为扩展自另外一个模型的主键;例如,多表继承就是通过对子模型添加一个隐式的一对一关联关系到父模型实现的。
需要一个位置参数:与该模型关联的类。 它的工作方式与ForeignKey 完全一致,包括所有与递归关系和惰性关系相关的选项。
以下内容个人理解笔记:
class News(models.Model):
title = models.CharField(max_length=10)
favor = models.ManyToManyField('User',through="Favor",through_fields=("new_obj", 'user_obj'))
# obj = models.News.objects.get(id=1)
# v = obj.favor.all()
# print(v)
# obj.favor.add(1)不能用
# obj.favor.remove(1)不能用
# v = obj.favor.all()能用
# obj.favor.clear()能用,根据id删,不用name这个字段
# v = models.User.objects.all()
# v = models.User.objects.all().select_related('user_type')class User(models.Model):
name = models.CharField(max_length=10)
email = models.EmailField(max_length=10)
user_type = models.ForeignKey('UserType') # 一对多 # user_profile = models.ForeignKey('UserDetail',unique=True)
user_profile = models.OneToOneField('UserDetail') class UserDetail(models.Model):
pwd = models.CharField(max_length=32) class Favor(models.Model):
new_obj = models.ForeignKey('News',related_name="n")
user_obj = models.ForeignKey('User',related_name='u')
name = models.CharField(max_length=64,null=True,blank=True) class UserType(models.Model):
name = models.CharField(max_length=10)
访问外键(Foreign Key)值
python manage.py shell
当你获取一个ForeignKey 字段时,你会得到相关的数据模型对象。
>>> from django.db import connection
>>> from app01.models import User
>>> u=User.objects.get(id=1)
>>> u
<User: User object>
>>> u.user_type
<UserType: UserType object>
>>> u.user_type.name
'type1'
对于用ForeignKey 来定义的关系来说,在关系的另一端也能反向的追溯回来,
通过一个UserType对象,直接获取 user ,用 UserType.user_set.all() ,
实际上,user_set 只是一个 QuerySet(参考第5章的介绍),
所以它可以像QuerySet一样,能实现数据过滤和分切,属性名称user_set是由模型名称的小写加_set组成的。
>>> from app01.models import UserType
>>> t=UserType.objects.get(name='type1')
>>> t.user_set.all()
<QuerySet [<User: User object>, <User: User object>]>
多对多
正向查找
>>> from app01.models import News
>>> n=News.objects.get(id=1)
>>> n.favor.all()
<QuerySet [<User: User object>, <User: User object>]>
>>> n.favor.filter(name='nu1')
<QuerySet [<User: User object>]>
反向查找
>>> u.news_set.all()
<QuerySet [<News: News object>]>
Python Web框架篇:Django Model基础的更多相关文章
- Python开发【第二十一篇】:Web框架之Django【基础】
Python开发[第二十一篇]:Web框架之Django[基础] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5237704.html Python之 ...
- Python开发【第十八篇】Web框架之Django【基础篇】
一.简介 Python下有许多款不同的 Web 框架,Django 是重量级选手中最有代表性的一位,许多成功的网站和APP都基于 Django. Django 是一个开放源代码的Web应用框架,由 P ...
- python web框架——扩展Django&tornado
一 Django自定义分页 目的:自定义分页功能,并把它写成模块(注意其中涉及到的python基础知识) models.py文件 # Create your models here. class Us ...
- 浅谈Python Web 框架:Django, Twisted, Tornado, Flask, Cyclone 和 Pyramid
Django Django 是一个高级的 Python Web 框架,支持快速开发,简洁.实用的设计.如果你正在建一个和电子商务网站相似的应用,那你应该选择用 Django 框架.它能使你快速完成工作 ...
- 两个Python web框架:Django & Tornado比较
就是说它作为 web 框架比 Django 简单,又支援异步 IO,且更不需要前端的 webserver ? 我已经混乱了, Tornado是 Nginx.Django.Node.js 的结合体?又或 ...
- 选择一个 Python Web 框架:Django vs Flask vs Pyramid
Pyramid, Django, 和 Flask都是优秀的框架,为项目选择其中的哪一个都是伤脑筋的事.我们将会用三种框架实现相同功能的应用来更容易的对比三者.也可以直接跳到框架实战(Framework ...
- [ 转载 ] Python Web 框架:Django、Flask 与 Tornado 的性能对比
本文的数据涉及到我面试时遇到过的问题,大概一次 http 请求到收到响应需要多少时间.这个问题在实际工作中与框架有比较大的关系,因此特别就框架的性能做了一次分析. 这里使用 2016 年 6 月 9 ...
- python web框架之django环境搭建
一.django环境搭建 https://www.djangoproject.com/download/ 下载适合自己的版本,在右边有压缩包版本的,也可以到git上去拽.我用的python27,下载的 ...
- Python Web框架篇:Django Model ORM(对象关系映射)
一,基本操作 用于实现面向对象编程语言里不同类型系统的数据之间的转换,换言之,就是用面向对象的方式去操作数据库的创建表以及增删改查等操作. 1.增(create , save): from app01 ...
随机推荐
- mongoDB学习手记2--建库、删库、插入、更新
上一篇 讲了在windows系统下的安装和启动,本文主要讲怎么建库.删库.插入.更新 在讲之前我们说一下mongoDB的一些基本概念,我们对比关系型数据库能更直观的理解 SQL术语/概念 Mongo ...
- java编程基础复习-------第二章
一.标识符 java中标识符的命名规则: 以数字.字母.下划线和$符号组成:不能用数字开头:不能是java的关键字. 注意:不要用$命名标识符.习惯上,$只用在机器自动产生的源代码中. 二.关键字 1 ...
- 用matlab给图像加高斯噪声和椒盐噪声(不调用imnoise函数)
图像画面中的噪声,大致可以分为两类:高斯噪声和椒盐噪声.在这里,我们先看下图像中两种噪声各自的特征. 椒盐噪声:噪声幅值基本相同,但出现位置随机. 高斯噪声:图像中每一点都存在噪声,但幅值是随机分布的 ...
- Sequence query 好题啊
Sequence query Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Subm ...
- P1050
问题 F: P1050 时间限制: 1 Sec 内存限制: 128 MB提交: 37 解决: 27[提交][状态][讨论版] 题目描述 一个字符串A的子串被定义成从A中顺次选出若干个字符构成的串. ...
- Monit : 开源监控工具介绍
· Monit 简介 Monit是一个轻量级(500KB)跨平台的用来监控Unix/linux系统的开源工具.部署简单,并且不依赖任何第三方程序.插件或者库. Monit可以监控服务器进程.文件.文件 ...
- Jquery.Uploadify实现批量上传显示进度条 取消 上传后缩略图显示 可删除
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="UpLoad.aspx.cs&q ...
- Spring ——简介及环境搭建跑通Hello
Spring Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.是为了解决企业应用程序开发复杂性而创建的.框架的主要优 ...
- [Python]Codecombat攻略之地牢Kithgard(1-22关)
首页:https://cn.codecombat.com/play语言:Python 第一界面:地牢 Kithgard(22关) 时间:1-3小时 内容:语法.方法.参数.字符串.循环.变量等 网页: ...
- SAP资产折旧,消息编号AA687:在上一年结算之后您只能记帐到新的一年
问题:公司****在2015年底没有固定资产,忽略了月结的必要步骤,在2016年1-5月份一直没有计提折旧,再进行折旧时提示"在上一年结算之后您只能记帐到新的一年" 原因: sap ...