当前位置: 首页 > news >正文

深圳深度网站建设小厂建网站

深圳深度网站建设,小厂建网站,wordpress 插件 二次元,网站开发工资咋样1.ORM介绍 ORM概念 对象关系映射#xff08;Object Relational Mapping#xff0c;简称ORM#xff09;模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说#xff0c;ORM是通过使用描述对象和数据库之间映射的元数据#xff0c;将程序中的对…1.ORM介绍 ORM概念 对象关系映射Object Relational Mapping简称ORM模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说ORM是通过使用描述对象和数据库之间映射的元数据将程序中的对象自动持久化到关系数据库中。 ORM在业务逻辑层和数据库层之间充当了桥梁的作用。 ORM由来 让我们从O/R开始。字母O起源于对象(Object)而R则来自于关系(Relational)。 几乎所有的软件开发过程中都会涉及到对象和关系数据库。在用户层面和业务逻辑层面我们是面向对象的。当对象的信息发生变化的时候我们就需要把对象的信息保存在关系数据库中。 按照之前的方式来进行开发就会出现程序员会在自己的业务逻辑代码中夹杂很多SQL语句用来增加、读取、修改、删除相关数据而这些代码通常都是极其相似或者重复的。 ORM的优势 ORM解决的主要问题是对象和关系的映射。它通常将一个类和一张表一一对应类的每个实例对应表中的一条记录类的每个属性对应表中的每个字段。 ORM提供了对数据库的映射不用直接编写SQL代码只需操作对象就能对数据库操作数据。 让软件开发人员专注于业务逻辑的处理提高了开发效率。 ORM劣势 ORM的缺点是会在一定程度上牺牲程序的执行效率。 ORM的操作是有限的也就是ORM定义好的操作是可以完成的一些复杂的查询操作是完成不了。 ORM用多了SQL语句就不会写了关系数据库相关技能退化... ORM总结 ORM只是一种工具工具确实能解决一些重复简单的劳动。这是不可否认的。 但我们不能指望某个工具能一劳永逸地解决所有问题一些特殊问题还是需要特殊处理的。 但是在整个软件开发过程中需要特殊处理的情况应该都是很少的否则所谓的工具也就失去了它存在的意义。 2.Django中数据库配置 1 django默认支持sqlitemysql, oracle,postgresql数据库。 ​ 1 sqlite ​ django默认使用sqlite的数据库默认自带sqlite的数据库驱动 。 引擎名称django.db.backends.sqlite3 ​ 2 mysql ​ 引擎名称django.db.backends.mysql 2 mysql驱动程序 MySQLdb(mysql python)mysqlclientMySQLPyMySQL(纯python的mysql驱动程序) 3 在django的项目中会默认使用sqlite数据库在settings里有如下设置 如果我们需要更改数据库,需要修改如下: DATABASES {default: {ENGINE: django.db.backends.mysql, NAME: books, #你的数据库名称USER: root, #你的数据库用户名PASSWORD: , #你的数据库密码HOST: , #你的数据库主机留空默认为localhostPORT: 3306, #你的数据库端口} }注意: 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()3.Model 在Django中model是你数据的单一、明确的信息来源。它包含了你存储的数据的重要字段和行为。通常一个模型model映射到一个数据库表。 基本情况 每个模型都是一个Python类它是django.db.models.Model的子类。模型的每个属性都代表一个数据库字段。综上所述Django为您提供了一个自动生成的数据库访问API详询官方文档链接。 4.字段 常用字段 AutoField 自增的整形字段必填参数primary_keyTrue则成为数据库的主键。无该字段时django自动创建。 一个model不能有两个AutoField字段。 IntegerField 一个整数类型。数值的范围是 -2147483648 ~ 2147483647。 CharField 字符类型必须提供max_length参数。max_length表示字符的长度。 DateField 日期类型日期格式为YYYY-MM-DD相当于Python中的datetime.date的实例。 参数 auto_now每次修改时修改为当前日期时间。auto_now_add新创建对象时自动添加当前日期时间。 auto_now和auto_now_add和default参数是互斥的不能同时设置。 DatetimeField 日期时间字段格式为YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]相当于Python中的datetime.datetime的实例。 字段类型详情可点击查询官网。 #字段类型AutoField(Field)- int自增列必须填入参数 primary_keyTrueBigAutoField(AutoField)- bigint自增列必须填入参数 primary_keyTrue注当model中如果没有自增列则自动会创建一个列名为id的列from django.db import modelsclass UserInfo(models.Model):# 自动创建一个列名为id的且为自增的整数列username models.CharField(max_length32)class Group(models.Model):# 自定义自增列nid models.AutoField(primary_keyTrue)name models.CharField(max_length32)SmallIntegerField(IntegerField):- 小整数 -32768 32767PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)- 正小整数 0 32767IntegerField(Field)- 整数列(有符号的) -2147483648 2147483647PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)- 正整数 0 2147483647BigIntegerField(IntegerField):- 长整型(有符号的) -9223372036854775808 9223372036854775807BooleanField(Field)- 布尔值类型NullBooleanField(Field):- 可以为空的布尔值CharField(Field)- 字符类型- 必须提供max_length参数 max_length表示字符长度TextField(Field)- 文本类型EmailField(CharField)- 字符串类型Django Admin以及ModelForm中提供验证机制IPAddressField(Field)- 字符串类型Django Admin以及ModelForm中提供验证 IPV4 机制GenericIPAddressField(Field)- 字符串类型Django Admin以及ModelForm中提供验证 Ipv4和Ipv6- 参数protocol用于指定Ipv4或Ipv6 both,ipv4,ipv6unpack_ipv4 如果指定为True则输入::ffff:192.0.2.1时候可解析为192.0.2.1开启此功能需要protocolbothURLField(CharField)- 字符串类型Django Admin以及ModelForm中提供验证 URLSlugField(CharField)- 字符串类型Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符减号CommaSeparatedIntegerField(CharField)- 字符串类型格式必须为逗号分割的数字UUIDField(Field)- 字符串类型Django Admin以及ModelForm中提供对UUID格式的验证FilePathField(Field)- 字符串Django Admin以及ModelForm中提供读取文件夹下文件的功能- 参数path, 文件夹路径matchNone, 正则匹配recursiveFalse, 递归下面的文件夹allow_filesTrue, 允许文件allow_foldersFalse, 允许文件夹FileField(Field)- 字符串路径保存在数据库文件上传到指定目录- 参数upload_to 上传文件的保存路径storage None 存储组件默认django.core.files.storage.FileSystemStorageImageField(FileField)- 字符串路径保存在数据库文件上传到指定目录- 参数upload_to 上传文件的保存路径storage None 存储组件默认django.core.files.storage.FileSystemStoragewidth_fieldNone, 上传图片的高度保存的数据库字段名字符串height_fieldNone 上传图片的宽度保存的数据库字段名字符串DateTimeField(DateField)- 日期时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]DateField(DateTimeCheckMixin, Field)- 日期格式 YYYY-MM-DDTimeField(DateTimeCheckMixin, Field)- 时间格式 HH:MM[:ss[.uuuuuu]]DurationField(Field)- 长整数时间间隔数据库中按照bigint存储ORM中获取的值为datetime.timedelta类型FloatField(Field)- 浮点型DecimalField(Field)- 10进制小数- 参数max_digits小数总长度decimal_places小数位长度BinaryField(Field)- 二进制类型 自定义字段 自定义一个二进制字段以及Django字段与数据库字段类型的对应关系。 class UnsignedIntegerField(models.IntegerField):def db_type(self, connection):return integer UNSIGNED# PS: 返回值为字段在数据库中的属性。 # Django字段与数据库字段类型对应关系如下AutoField: integer AUTO_INCREMENT,BigAutoField: bigint AUTO_INCREMENT,BinaryField: longblob,BooleanField: bool,CharField: varchar(%(max_length)s),CommaSeparatedIntegerField: varchar(%(max_length)s),DateField: date,DateTimeField: datetime,DecimalField: numeric(%(max_digits)s, %(decimal_places)s),DurationField: bigint,FileField: varchar(%(max_length)s),FilePathField: varchar(%(max_length)s),FloatField: double precision,IntegerField: integer,BigIntegerField: bigint,IPAddressField: char(15),GenericIPAddressField: char(39),NullBooleanField: bool,OneToOneField: integer,PositiveIntegerField: integer UNSIGNED,PositiveSmallIntegerField: smallint UNSIGNED,SlugField: varchar(%(max_length)s),SmallIntegerField: smallint,TextField: longtext,TimeField: time,UUIDField: char(32),自定义一个char类型字段 class MyCharField(models.Field):自定义的char类型的字段类def __init__(self, max_length, *args, **kwargs):self.max_length max_lengthsuper(MyCharField, self).__init__(max_lengthmax_length, *args, **kwargs)def db_type(self, connection):限定生成数据库表的字段类型为char长度为max_length指定的值return char(%s) % self.max_length使用自定义char类型字段 class Class(models.Model):id models.AutoField(primary_keyTrue)title models.CharField(max_length25)# 使用自定义的char类型的字段cname MyCharField(max_length25)创建的表结构 字段参数 字段参数详情可点击查看官网。 null 数据库中字段是否可以为空db_column 数据库中字段的列名default 数据库中字段的默认值primary_key 数据库中字段是否为主键db_index 数据库中字段是否可以建立索引unique 数据库中字段是否可以建立唯一索引unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引unique_for_month 数据库中字段【月】部分是否可以建立唯一索引unique_for_year 数据库中字段【年】部分是否可以建立唯一索引verbose_name Admin中显示的字段名称blank Admin中是否允许用户输入为空editable Admin中是否可以编辑help_text Admin中该字段的提示信息choices Admin中显示选择框的内容用不变动的数据放在内存中从而避免跨表操作如gf models.IntegerField(choices[(0, 何穗),(1, 大表姐),],default1)error_messages 自定义错误信息字典类型从而定制想要显示的错误信息字典健null, blank, invalid, invalid_choice, unique, and unique_for_date如{null: 不能为空., invalid: 格式错误}validators 自定义错误验证列表类型从而定制想要的验证规则from django.core.validators import RegexValidatorfrom django.core.validators import EmailValidator,URLValidator,DecimalValidator,\MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator如test models.CharField(max_length32,error_messages{c1: 优先错信息1,c2: 优先错信息2,c3: 优先错信息3,},validators[RegexValidator(regexroot_\d, message错误了, codec1),RegexValidator(regexroot_112233\d, message又错误了, codec2),EmailValidator(message又错误了, codec3), ]) Model Meta参数 这个不是很常用如果你有特殊需要可以使用。详情点击查看官网。 class UserInfo(models.Model):nid models.AutoField(primary_keyTrue)username models.CharField(max_length32)class Meta:# 数据库中生成的表名称 默认 app名称 下划线 类名db_table table_name# admin中显示的表名称verbose_name 个人信息# verbose_name加sverbose_name_plural 所有用户信息# 联合索引 index_together [(pub_date, deadline), # 应为两个存在的字段]# 联合唯一索引unique_together ((driver, restaurant),) # 应为两个存在的字段多表关系和参数 ForeignKey(ForeignObject) # ForeignObject(RelatedField)to, # 要进行关联的表名to_fieldNone, # 要关联的表中的字段名称on_deleteNone, # 当删除关联表中的数据时当前表与其关联的行的行为- models.CASCADE删除关联数据与之关联也删除- models.DO_NOTHING删除关联数据引发错误IntegrityError- models.PROTECT删除关联数据引发错误ProtectedError- models.SET_NULL删除关联数据与之关联的值设置为null前提FK字段需要设置为可空- models.SET_DEFAULT删除关联数据与之关联的值设置为默认值前提FK字段需要设置默认值- models.SET删除关联数据a. 与之关联的值设置为指定值设置models.SET(值)b. 与之关联的值设置为可执行对象的返回值设置models.SET(可执行对象)def func():return 10class MyModel(models.Model):user models.ForeignKey( toUser, to_fieldid on_deletemodels.SET(func),)related_nameNone, # 反向操作时使用的字段名用于代替 【表名_set】 如 obj.表名_set.all() related_query_nameNone, # 反向操作时使用的连接前缀用于替换【表名】 如 models.UserGroup.objects.filter(表名__字段名1).values(表名__字段名) limit_choices_toNone, # 在Admin或ModelForm中显示关联数据时提供的条件# 如- limit_choices_to{nid__gt: 5}- limit_choices_tolambda : {nid__gt: 5}from django.db.models import Q- limit_choices_toQ(nid__gt10)- limit_choices_toQ(nid8) | Q(nid__gt10)- limit_choices_tolambda : Q(Q(nid8) | Q(nid__gt10)) Q(captionroot)db_constraintTrue # 是否在数据库中创建外键约束parent_linkFalse # 在Admin中是否显示关联数据OneToOneField(ForeignKey)to, # 要进行关联的表名to_fieldNone # 要关联的表中的字段名称on_deleteNone, # 当删除关联表中的数据时当前表与其关联的行的行为###### 对于一对一 ####### 1. 一对一其实就是 一对多 唯一索引# 2.当两个类之间有继承关系时默认会创建一个一对一字段# 如下会在A表中额外增加一个c_ptr_id列且唯一class C(models.Model):nid models.AutoField(primary_keyTrue)part models.CharField(max_length12)class A(C):id models.AutoField(primary_keyTrue)code models.CharField(max_length1)ManyToManyField(RelatedField)to, # 要进行关联的表名related_nameNone, # 反向操作时使用的字段名用于代替 【表名_set】 如 obj.表名_set.all()related_query_nameNone, # 反向操作时使用的连接前缀用于替换【表名】 如 models.UserGroup.objects.filter(表名__字段名1).values(表名__字段名)limit_choices_toNone, # 在Admin或ModelForm中显示关联数据时提供的条件# 如- limit_choices_to{nid__gt: 5}- limit_choices_tolambda : {nid__gt: 5}from django.db.models import Q- limit_choices_toQ(nid__gt10)- limit_choices_toQ(nid8) | Q(nid__gt10)- limit_choices_tolambda : Q(Q(nid8) | Q(nid__gt10)) Q(captionroot)symmetricalNone, # 仅用于多对多自关联时symmetrical用于指定内部是否创建反向操作的字段# 做如下操作时不同的symmetrical会有不同的可选字段models.BB.objects.filter(...)# 可选字段有code, id, m1class BB(models.Model):code models.CharField(max_length12)m1 models.ManyToManyField(self,symmetricalTrue)# 可选字段有: bb, code, id, m1 class BB(models.Model):code models.CharField(max_length12)m1 models.ManyToManyField(self,symmetricalFalse)throughNone, # 自定义第三张表时使用字段用于指定关系表through_fieldsNone, # 自定义第三张表时使用字段用于指定关系表中那些字段做多对多关系表 from django.db import modelsclass Person(models.Model):name models.CharField(max_length50)class Group(models.Model):name models.CharField(max_length128)members models.ManyToManyField(Person, throughMembership, through_fields(group, person))class Membership(models.Model): group models.ForeignKey(Group, on_deletemodels.CASCADE) person models.ForeignKey(Person, on_deletemodels.CASCADE) inviter models.ForeignKey(Person, on_deletemodels.CASCADE related_namemembership_invites,) invite_reason models.CharField(max_length64)db_constraintTrue, # 是否在数据库中创建外键约束db_tableNone, # 默认创建第三张表时数据库中表的名称ORM基本操作 # 增 models.Tb1.objects.create(c1xx, c2oo) # 增加一条数据可以接受字典类型数据 **kwargs obj models.Tb1(c1xx, c2oo) obj.save()# 查 models.Tb1.objects.get(id123) # 获取单条数据不存在则报错不建议 models.Tb1.objects.all() # 获取全部 models.Tb1.objects.filter(nameseven) # 获取指定条件的数据 models.Tb1.objects.exclude(nameseven) # 去除指定条件的数据# 删 # models.Tb1.objects.filter(nameseven).delete() # 删除指定条件的数据# 改 models.Tb1.objects.filter(nameseven).update(gender0) # 将指定条件的数据更新均支持 **kwargs obj models.Tb1.objects.get(id1) obj.c1 111 obj.save() # 修改单条数据进阶操作 # 获取个数 # # models.Tb1.objects.filter(nameseven).count()# 大于小于 # # models.Tb1.objects.filter(id__gt1) # 获取id大于1的值 # models.Tb1.objects.filter(id__gte1) # 获取id大于等于1的值 # models.Tb1.objects.filter(id__lt10) # 获取id小于10的值 # models.Tb1.objects.filter(id__lte10) # 获取id小于10的值 # models.Tb1.objects.filter(id__lt10, id__gt1) # 获取id大于1 且 小于10的值# 成员判断in # # models.Tb1.objects.filter(id__in[11, 22, 33]) # 获取id等于11、22、33的数据 # models.Tb1.objects.exclude(id__in[11, 22, 33]) # not in# 是否为空 isnull # Entry.objects.filter(pub_date__isnullTrue)# 包括contains # # models.Tb1.objects.filter(name__containsven) # models.Tb1.objects.filter(name__icontainsven) # icontains大小写不敏感 # models.Tb1.objects.exclude(name__icontainsven)# 范围range # # models.Tb1.objects.filter(id__range[1, 2]) # 范围bettwen and# 其他类似 # # startswithistartswith, endswith, iendswith,# 排序order by # # models.Tb1.objects.filter(nameseven).order_by(id) # asc # models.Tb1.objects.filter(nameseven).order_by(-id) # desc# 分组group by # # from django.db.models import Count, Min, Max, Sum # models.Tb1.objects.filter(c11).values(id).annotate(cCount(num)) # SELECT app01_tb1.id, COUNT(app01_tb1.num) AS c FROM app01_tb1 WHERE app01_tb1.c1 1 GROUP BY app01_tb1.id# limit 、offset # # models.Tb1.objects.all()[10:20]# regex正则匹配iregex 不区分大小写 # # Entry.objects.get(title__regexr^(An?|The) ) # Entry.objects.get(title__iregexr^(an?|the) )# date # # Entry.objects.filter(pub_date__datedatetime.date(2005, 1, 1)) # Entry.objects.filter(pub_date__date__gtdatetime.date(2005, 1, 1))# year # # Entry.objects.filter(pub_date__year2005) # Entry.objects.filter(pub_date__year__gte2005)# month # # Entry.objects.filter(pub_date__month12) # Entry.objects.filter(pub_date__month__gte6)# day # # Entry.objects.filter(pub_date__day3) # Entry.objects.filter(pub_date__day__gte3)# week_day # # Entry.objects.filter(pub_date__week_day2) # Entry.objects.filter(pub_date__week_day__gte2)# hour # # Event.objects.filter(timestamp__hour23) # Event.objects.filter(time__hour5) # Event.objects.filter(timestamp__hour__gte12)# minute # # Event.objects.filter(timestamp__minute29) # Event.objects.filter(time__minute46) # Event.objects.filter(timestamp__minute__gte29)# second # # Event.objects.filter(timestamp__second31) # Event.objects.filter(time__second2) # Event.objects.filter(timestamp__second__gte31)高级操作 # extra # 在QuerySet的基础上继续执行子语句 # extra(self, selectNone, whereNone, paramsNone, tablesNone, order_byNone, select_paramsNone)# select和select_params是一组where和params是一组tables用来设置from哪个表 # Entry.objects.extra(select{new_id: select col from sometable where othercol %s}, select_params(1,)) # Entry.objects.extra(where[headline%s], params[Lennon]) # Entry.objects.extra(where[fooa OR bar a, baz a]) # Entry.objects.extra(select{new_id: select id from tb where id %s}, select_params(1,), order_by[-nid])举个例子 models.UserInfo.objects.extra(select{newid:select count(1) from app01_usertype where id%s},select_params[1,],where [age%s],params[18,],order_by[-age],tables[app01_usertype])select app01_userinfo.id,(select count(1) from app01_usertype where id1) as newidfrom app01_userinfo,app01_usertypewhere app01_userinfo.age 18order by app01_userinfo.age desc# 执行原生SQL # 更高灵活度的方式执行原生SQL语句 # from django.db import connection, connections # cursor connection.cursor() # cursor connections[default].cursor() # cursor.execute(SELECT * from auth_user where id %s, [1]) # row cursor.fetchone()QuerySet相关操作 ################################################################## # PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET # ##################################################################def all(self)# 获取所有的数据对象def filter(self, *args, **kwargs)# 条件查询# 条件可以是参数字典Qdef exclude(self, *args, **kwargs)# 条件查询# 条件可以是参数字典Qdef select_related(self, *fields)性能相关表之间进行join连表操作一次性获取关联的数据。总结1. select_related主要针一对一和多对一关系进行优化。2. select_related使用SQL的JOIN语句进行优化通过减少SQL查询的次数来进行优化、提高性能。def prefetch_related(self, *lookups)性能相关多表连表操作时速度会慢使用其执行多次SQL查询在Python代码中实现连表操作。总结1. 对于多对多字段ManyToManyField和一对多字段可以使用prefetch_related()来进行优化。2. prefetch_related()的优化方式是分别查询每个表然后用Python处理他们之间的关系。def annotate(self, *args, **kwargs)# 用于实现聚合group by查询from django.db.models import Count, Avg, Max, Min, Sumv models.UserInfo.objects.values(u_id).annotate(uidCount(u_id))# SELECT u_id, COUNT(ui) AS uid FROM UserInfo GROUP BY u_idv models.UserInfo.objects.values(u_id).annotate(uidCount(u_id)).filter(uid__gt1)# SELECT u_id, COUNT(ui_id) AS uid FROM UserInfo GROUP BY u_id having count(u_id) 1v models.UserInfo.objects.values(u_id).annotate(uidCount(u_id,distinctTrue)).filter(uid__gt1)# SELECT u_id, COUNT( DISTINCT ui_id) AS uid FROM UserInfo GROUP BY u_id having count(u_id) 1def distinct(self, *field_names)# 用于distinct去重models.UserInfo.objects.values(nid).distinct()# select distinct nid from userinfo注只有在PostgreSQL中才能使用distinct进行去重def order_by(self, *field_names)# 用于排序models.UserInfo.objects.all().order_by(-id,age)def extra(self, selectNone, whereNone, paramsNone, tablesNone, order_byNone, select_paramsNone)# 构造额外的查询条件或者映射如子查询Entry.objects.extra(select{new_id: select col from sometable where othercol %s}, select_params(1,))Entry.objects.extra(where[headline%s], params[Lennon])Entry.objects.extra(where[fooa OR bar a, baz a])Entry.objects.extra(select{new_id: select id from tb where id %s}, select_params(1,), order_by[-nid])def reverse(self):# 倒序models.UserInfo.objects.all().order_by(-nid).reverse()# 注如果存在order_byreverse则是倒序如果多个排序则一一倒序def defer(self, *fields):models.UserInfo.objects.defer(username,id)或models.UserInfo.objects.filter(...).defer(username,id)#映射中排除某列数据def only(self, *fields):#仅取某个表中的数据models.UserInfo.objects.only(username,id)或models.UserInfo.objects.filter(...).only(username,id)def using(self, alias):指定使用的数据库参数为别名setting中的设置################################################## # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS # ##################################################def raw(self, raw_query, paramsNone, translationsNone, usingNone):# 执行原生SQLmodels.UserInfo.objects.raw(select * from userinfo)# 如果SQL是其他表时必须将名字设置为当前UserInfo对象的主键列名models.UserInfo.objects.raw(select id as nid from 其他表)# 为原生SQL设置参数models.UserInfo.objects.raw(select id as nid from userinfo where nid%s, params[12,])# 将获取的到列名转换为指定列名name_map {first: first_name, last: last_name, bd: birth_date, pk: id}Person.objects.raw(SELECT * FROM some_other_table, translationsname_map)# 指定数据库models.UserInfo.objects.raw(select * from userinfo, usingdefault)################### 原生SQL ###################from django.db import connection, connectionscursor connection.cursor() # cursor connections[default].cursor()cursor.execute(SELECT * from auth_user where id %s, [1])row cursor.fetchone() # fetchall()/fetchmany(..)def values(self, *fields):# 获取每行数据为字典格式def values_list(self, *fields, **kwargs):# 获取每行数据为元祖def dates(self, field_name, kind, orderASC):# 根据时间进行某一部分进行去重查找并截取指定内容# kind只能是year年, month年-月, day年-月-日# order只能是ASC DESC# 并获取转换后的时间- year : 年-01-01- month: 年-月-01- day : 年-月-日models.DatePlus.objects.dates(ctime,day,DESC)def datetimes(self, field_name, kind, orderASC, tzinfoNone):# 根据时间进行某一部分进行去重查找并截取指定内容将时间转换为指定时区时间# kind只能是 year, month, day, hour, minute, second# order只能是ASC DESC# tzinfo时区对象models.DDD.objects.datetimes(ctime,hour,tzinfopytz.UTC)models.DDD.objects.datetimes(ctime,hour,tzinfopytz.timezone(Asia/Shanghai))pip3 install pytzimport pytzpytz.all_timezonespytz.timezone(‘Asia/Shanghai’)def none(self):# 空QuerySet对象#################################### # METHODS THAT DO DATABASE QUERIES # ####################################def aggregate(self, *args, **kwargs):# 聚合函数获取字典类型聚合结果from django.db.models import Count, Avg, Max, Min, Sumresult models.UserInfo.objects.aggregate(kCount(u_id, distinctTrue), nCount(nid)) {k: 3, n: 4}def count(self):# 获取个数def get(self, *args, **kwargs):# 获取单个对象def create(self, **kwargs):# 创建对象def bulk_create(self, objs, batch_sizeNone):# 批量插入# batch_size表示一次插入的个数objs [models.DDD(namer11),models.DDD(namer22)]models.DDD.objects.bulk_create(objs, 10)def get_or_create(self, defaultsNone, **kwargs):# 如果存在则获取否则创建# defaults 指定创建时其他字段的值obj, created models.UserInfo.objects.get_or_create(usernameroot1, defaults{email: 1111111,u_id: 2, t_id: 2})def update_or_create(self, defaultsNone, **kwargs):# 如果存在则更新否则创建# defaults 指定创建时或更新时的其他字段obj, created models.UserInfo.objects.update_or_create(usernameroot1, defaults{email: 1111111,u_id: 2, t_id: 1})def first(self):# 获取第一个def last(self):# 获取最后一个def in_bulk(self, id_listNone):# 根据主键ID进行查找id_list [11,21,31]models.DDD.objects.in_bulk(id_list)def delete(self):# 删除def update(self, **kwargs):# 更新def exists(self):# 是否有结果5.ORM之创建表操作 在配置好数据库后,创建一张表的操作如下 首先在models.py文件中,创建一个类,例如: class UserInfo(models.Model):id models.AutoField(primary_keyTrue)name models.CharField(max_length10)bday models.DateField()checked models.BooleanField()通过两条数据库迁移命令即可在指定的数据库中创建表 python manage.py makemigrations #生成记录每次修改了models里面的内容或者添加了新的app新的app里面写了models里面的内容都要执行这两条 python manage.py migrate #执行上面这个语句的记录来创建表生成的表名字前面会自带应用的名字例如你的book表在mysql里面叫做app01_book表关于同步指令的执行简单原理: 在执行 python manager.py magrations 时django会在相应的app的migration文件夹下面生成一个python脚本文件 在执行 python manager.py migrte 时 django才会生成数据库表那么django是如何生成数据库表的呢django是根据 migration下面的脚本文件来生成数据表的每个migration文件夹下面有多个脚本那么django是如何知道该执行那个文件的呢django有一张django-migrations表表中记录了已经执行的脚本那么表中没有的就是还没执行的脚本则 执行migrate的时候就只执行表中没有记录的那些脚本。有时在执行 migrate 的时候如果发现没有生成相应的表可以看看在 django-migrations表中看看 脚本是否已经执行了可以删除 django-migrations 表中的记录和数据库中相应的表,然后重新 执行6.ORM中的锁和事务 锁 行级锁 select_for_update(nowaitFalse,skip_lockedFalse) #注意必须用在事务里面 返回一个锁住行直到事务结束的查询集,如果数据库支持,它将生成一个select...for uppdate语句 举例:models.Book.objects.select_for_update().filter(id1)#加互斥锁,由于mysql在查询时自动加的就是共享锁,所以可以手动加上互斥锁,.create,update,delete操作时,mysql自动加行级互斥锁 所有匹配的行将被锁定,直到事务结束,这意味着可以通过锁防止数据被其他事务修改. 一般情况下如果其他事务锁定了相关行那么本查询将被阻塞直到锁被释放。 如果这不想要使查询阻塞的话使用select_for_update(nowaitTrue)。 如果其它事务持有冲突的锁互斥锁, 那么查询将引发 DatabaseError 异常。你也可以使用select_for_update(skip_lockedTrue)忽略锁定的行。 nowait和  skip_locked是互斥的同时设置会导致ValueError。 目前postgresqloracle和mysql数据库后端支持select_for_update()。 但是MySQL不支持nowait和skip_locked参数。 使用不支持这些选项的数据库后端如MySQL将nowaitTrue或skip_lockedTrue转换为select_for_update()将导致抛出DatabaseError异常这可以防止代码意外终止。 事务 1.全局开启 在Web应用中常用的事务处理方式是将每个请求都包裹在一个事务中。这个功能使用起来非常简单你只需要将它的配置项ATOMIC_REQUESTS设置为True。 它是这样工作的当有请求过来时Django会在调用视图方法前开启一个事务。如果请求却正确处理并正确返回了结果Django就会提交该事务。否则Django会回滚该事务。 DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: mxshop,HOST: 127.0.0.1,PORT: 3306,USER: root,PASSWORD: 123,OPTIONS: {init_command: SET default_storage_engineINNODB,#init_command: SET sql_modeSTRICT_TRANS_TABLES, #配置开启严格sql模式}ATOMIC_REQUESTS: True, #全局开启事务绑定的是http请求响应整个过程AUTOCOMMIT:False, #全局取消自动提交慎用}other:{ENGINE: django.db.backends.mysql, ......} #还可以配置其他数据库 } 上面这种方式是统一个http请求对应的所有sql都放在一个事务中执行要么所有都成功要么所有都失败。是全局性的配置 如果要对某个http请求放水然后自定义事务可以用non_atomic_requests修饰器那么他就不受事务的管控了. from django.db import transactiontransaction.non_atomic_requests def my_view(request):do_stuff()transaction.non_atomic_requests(usingother) def my_other_view(request):do_stuff_on_the_other_database() 但是Django 文档中说不推荐这么做。因为如果将事务跟 HTTP 请求绑定到一起的时然而view 是依赖于应用程序对数据库的查询语句效率和数据库当前的锁竞争情况。当流量上来的时候性能会有影响知道一下就行了 所以推荐用下面这种方式通过 transaction.atomic 来更加明确的控制事务。atomic允许我们在执行代码块时在数据库层面提供原子性保证。 如果代码块成功完成 相应的变化会被提交到数据库进行commit如果执行期间遇到异常则会将该段代码所涉及的所有更改回滚。 2.局部使用事务 atomic(usingNone, savepointTrue)[source] 参数usingother,就是当你操作其他数据库的时候这个事务才生效看上面我们的数据库配置除了default还有一个other默认的是default。savepoint的意思是开启事务保存点. 原子性是数据库事务的一个属性。使用atomic我们就可以创建一个具备原子性的代码块。一旦代码块正常运行完毕所有的修改会被提交到数据库。反之如果有异常更改会被回滚。 被atomic管理起来的代码块还可以内嵌到方法中。这样的话即便内部代码块正常运行如果外部代码块抛出异常的话它也没有办法把它的修改提交到数据库中。 用法1给函数做装饰器来使用  from django.db import transactiontransaction.atomic def viewfunc(request):# This code executes inside a transaction.do_stuff() 用法2:作为上下文管理器来使用,其实就是设置事务的保存点 from django.db import transactiondef viewfunc(request):# This code executes in autocommit mode (Djangos default).do_stuff()with transaction.atomic(): #保存点# This code executes inside a transaction.do_more_stuff()do_other_stuff() 一旦把atomic代码块放到try/except中完整性错误就会被自然的处理掉了比如下面这个例子 from django.db import IntegrityError, transactiontransaction.atomic def viewfunc(request):create_parent()try:with transaction.atomic():generate_relationships()except IntegrityError:handle_exception()add_children() 用法3还可以嵌套使用函数的事务嵌套上下文管理器的事务上下文管理器的事务嵌套上下文管理器的事务等。下面的是函数嵌套上下文的例子 from django.db import IntegrityError, transactiontransaction.atomic def viewfunc(request):create_parent()try:with transaction.atomic():generate_relationships() #other_task() #还要注意一点如果你在事务里面写了别的操作只有这些操作全部完成之后事务才会commit也就是说如果你这个任务是查询上面更改的数据表里面的数据那么看到的还是事务提交之前的数据。except IntegrityError:handle_exception()add_children() 这个例子中即使generate_relationships()中的代码打破了数据完整性约束你仍然可以在add_children()中执行数据库操作并且create_parent()产生的更改也有效。需要注意的是在调用handle_exception()之前generate_relationships()中的修改就已经被安全的回滚了。因此如果有需要你照样可以在异常处理函数中操作数据库。 尽量不要在atomic代码块中捕获异常因为当atomic块中的代码执行完的时候Django会根据代码正常运行来执行相应的提交或者回滚操作。如果在atomic代码块里面捕捉并处理了异常就有可能隐盖代码本身的错误从而可能会有一些意料之外的不愉快事情发生。担心主要集中在DatabaseError和它的子类如IntegrityError。如果这种异常真的发生了事务就会被破坏掉而Django会在代码运行完后执行回滚操作。如果你试图在回滚前执行一些数据库操作Django会抛出TransactionManagementError。通常你会在一个ORM相关的信号处理器抛出异常时遇到这个行为。捕获异常的正确方式正如上面atomic代码块所示。如果有必要添加额外的atomic代码块来做这件事情也就是事务嵌套。这么做的好处是当异常发生时它能明确地告诉你那些操作需要回滚而那些是不需要的。 为了保证原子性atomic还禁止了一些API。像试图提交、回滚事务以及改变数据库连接的自动提交状态这些操作在atomic代码块中都是不予许的否则就会抛出异常。 下面是Django的事务管理代码 进入最外层atomic代码块时开启一个事务进入内部atomic代码块时创建保存点退出内部atomic时释放或回滚事务注意如果有嵌套内层的事务也是不会提交的可以释放正常结束或者回滚退出最外层atomic代码块时提交或者回滚事务 你可以将保存点参数设置成False来禁止内部代码块创建保存点。如果发生了异常Django在退出第一个父块的时候执行回滚如果存在保存点将回滚到这个保存点的位置否则就是回滚到最外层的代码块。外层事务仍然能够保证原子性。然而这个选项应该仅仅用于保存点开销较大的时候。毕竟它有个缺点会破坏上文描述的错误处理机制。 注意transaction只对数据库层的操作进行事务管理,不能理解为python操作的事务管理 def example_view(request):tag Falsewith transaction.atomic():tag Truechange_obj() # 修改对象变量obj.save()raise DataErrorprint(tag ,tag) #结果是True也就是说在事务中的python变量赋值即便是事务回滚了这个赋值也是成功的 还要注意如果你配置了全局的事务它和局部事务可能会产生冲突你可能会发现你局部的事务完成之后如果你的函数里面其他的sql除了问题也就是没在这个上下文管理器的局部事务包裹范围内的函数里面的其他的sql出现了问题你的局部事务也是提交不上的因为全局会回滚这个请求和响应所涉及到的所有的sql所以还是建议以后的项目尽量不要配置全局的事务通过局部事务来搞定当然了看你们的业务场景。 transaction的其他方法 transaction.atomic def viewfunc(request):a.save()# open transaction now contains a.save()sid transaction.savepoint() #创建保存点b.save()# open transaction now contains a.save() and b.save()if want_to_keep_b:transaction.savepoint_commit(sid) #提交保存点# open transaction still contains a.save() and b.save()else:transaction.savepoint_rollback(sid) #回滚保存点# open transaction now contains only a.save()transaction.commit() #手动提交事务默认是自动提交的也就是说如果你没有设置取消自动提交那么这句话不用写如果你配置了那个AUTOCOMMITFalse那么就需要自己手动进行提交。 为保证事务的隔离性我们还可以结合上面的锁来实现也就是说在事务里面的查询语句咱们使用select_for_update显示的加锁方式来保证隔离性事务结束后才会释放这个锁例如了解 transaction.atomic ## 轻松开启事务 def handle(self):## 测试是否存在此用户try:## 锁定被查询行直到事务结束user User.objects.select_for_update().get(open_idself.user.open_id)#other sql 语句except User.DoesNotExist:raise BaseError(-1, User does not exist.) 通过Django外部的python脚本来测试一下事务 import osif __name__ __main__:os.environ.setdefault(DJANGO_SETTINGS_MODULE, BMS.settings)import djangodjango.setup()import datetimefrom app01 import modelstry:from django.db import transactionwith transaction.atomic():new_publisher models.Publisher.objects.create(name火星出版社)models.Book.objects.create(title橘子物语, publish_datedatetime.date.today(), publisher_id10) # 指定一个不存在的出版社idexcept Exception as e:print(str(e)) 一些设置事务的小原则 ​    1.保持事务短小     2.尽量避免事务中rollback     3.尽量避免savepoint     4.默认情况下依赖于悲观锁     5.为吞吐量要求苛刻的事务考虑乐观锁     6.显示声明打开事务     7.锁的行越少越好锁的时间越短越好
http://www.w-s-a.com/news/212639/

相关文章:

  • 是做网站编辑还是做平面设计seo外包公司接单
  • 做性的网站有哪些苏州专业网站设计制作公司
  • 陵水网站建设友创科技十大优品店排名
  • 想换掉做网站的公司简要说明网站制作的基本步骤
  • 国企公司网站制作wordpress 浮动定位
  • 网站网页直播怎么做的企业网站建设推荐兴田德润
  • 网站建设熊猫建站厦门seo全网营销
  • 扁平网站设计seo是什么岗位的缩写
  • 工商企业网站群晖配置wordpress 80端口
  • 企业网站建设流程步骤镇江东翔网络科技有限公司
  • 网络工程师和做网站哪个难网络建站如何建成
  • 网站建设需要哪些项目游民星空是用什么做的网站
  • 旅游网站建设要如何做百度商城网站建设
  • destoon 网站搬家中国企业500强都有哪些企业
  • 商城网站前端更新商品天天做吗哈尔滨做网站优化
  • 新乡网站开发wordpress 产品分类侧边栏
  • 网站自己做自己的品牌好做互联网企业分类
  • 项目网站建设方案石家庄网站快速排名
  • 网站开发大作业报告做电商网站的参考书
  • Apache局域网网站制作wordpress外链自动保存
  • 网站备案号要怎么查询千锋教育培训机构地址
  • 门户网站建设要求几款免费流程图制作软件
  • 花生壳域名可以做网站域名吗wordpress内链工具
  • 猎头公司网站模板网站伪静态作用
  • 工程建设教育网站html成品网页模板下载
  • 同一ip 网站 权重wordpress 菜单 小图标
  • 网站没有icp备案wordpress d8主题 4.1
  • 手机网站建设推荐企业宣传页模板
  • 杭州市富阳区建设局网站动态域名做网站
  • 网站如何免费做SEO优化靖安县城乡规划建设局网站