Models.py数据操作
在模块编写上官方提供了教程https://docs.djangoproject.com/en/dev/topics/db/models/,但是官方教程很多地方不太详细。我们分几部分来进行讲解。
模块引用
在models.py中和模型相关的引用主要有以下两个(其他的引用主要看具体编写需求):
from django.db import models
这个引用相当于提供了模型建立的方法,models这个模块中包含了诸多的类一般都是和模型的构建相关。这个模块也是我们最常用的模块。
from django.contrib.auth.models import [需求类]
这个引用中的models模块和上个不同,是系统为我们自动提供的,其中为我们自动编写了像用户,用户组,权限等数据类模型。在我们同步数据库的时候这个模块中的数据模型会自动同步,我们可以使用系统提供的这些模型,当我们觉得原有模型不能满足我们需求的时候可以通过这样的import引入引入具体某个数据模型类,然后进行修改。这部分内容我们在模型的高级操作中会有介绍。
数据模型类的编写
基本结构:
from django.db import models
#如果没有models.AutoField,默认会创建一个id的自增列
class userinfo(models.Model):
name = models.CharField(max_length=30)
email =models.EmailField()
memo =models.TextField()
这是一个最基本的数据表类,数据表类需要继承models.Model ,这其中每个属性表示一个字段Field为字段类型,字段函数内的参数是对字段的描述(大小,默认值,可否为空等)。Django的模型中几乎支持了所有的数据库数据类型,关于更多类型的讲解可以查看上面提到的官方教程,在这里为大家简单列出:
字段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 1、models.AutoField 自增列= int(11) 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。 2、models.CharField 字符串字段 必须 max_length 参数 3、models.BooleanField 布尔类型=tinyint(1) 不能为空,Blank=True 4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar 继承CharField,所以必须 max_lenght 参数 5、models.DateField 日期类型 date 对于参数,auto_now =True则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。 6、models.DateTimeField 日期类型 datetime 同DateField的参数 7、models.Decimal 十进制小数类型= decimal 必须指定整数位max_digits和小数位decimal_places 8、models.EmailField 字符串类型(正则表达式邮箱)=varchar 对字符串进行正则表达式 9、models.FloatField 浮点类型= double 10、models.IntegerField 整形 11、models.BigIntegerField 长整形 integer_field_ranges ={ 'SmallIntegerField':(-32768,32767), 'IntegerField':(-2147483648,2147483647), 'BigIntegerField':(-9223372036854775808,9223372036854775807), 'PositiveSmallIntegerField':(0,32767), 'PositiveIntegerField':(0,2147483647), } 12、models.IPAddressField 字符串类型(ip4正则表达式) 13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的) 参数protocol可以是:both、ipv4、ipv6 验证时,会根据设置报错 14、models.NullBooleanField 允许为空的布尔类型 15、models.PositiveIntegerFiel 正Integer 16、models.PositiveSmallIntegerField 正smallInteger 17、models.SlugField 减号、下划线、字母、数字 18、models.SmallIntegerField 数字 数据库中的字段有:tinyint、smallint、int、bigint 19、models.TextField 字符串=longtext 20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]] 21、models.URLField 字符串,地址正则表达式 22、models.BinaryField 二进制 23、models.ImageField图片 24、models.FilePathField文件 |
参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 1、null=True 数据库中字段是否可以为空 2、blank=True django的Admin中添加数据时是否可允许空值 3、primary_key =False 主键,对AutoField设置主键后,就会代替原来的自增 id 列 4、auto_now 和 auto_now_add auto_now 自动创建---无论添加或修改,都是当前操作的时间 auto_now_add 自动创建---永远是创建时的时间 5、choices GENDER_CHOICE =( (u'M', u'Male'), (u'F', u'Female'), ) gender = models.CharField(max_length=2,choices = GENDER_CHOICE) 6、max_length 7、default 默认值 8、verbose_name Admin中字段的显示名称 9、name|db_column 数据库中的字段名称 10、unique=True 不允许重复 11、db_index =True 数据库索引 12、editable=True 在Admin里是否可编辑 13、error_messages=None 错误提示 14、auto_created=False 自动创建 15、help_text 在Admin中提示帮助信息 16、validators=[] 17、upload-to |
数据库的同步
当我们创建好数据类后就可以进行数据库的同步操作了。这依赖于manage.py命令。
1. 同步数据
在django1.7以前使用的命令是 python manage.py syncdb 但是在1.7以后就不再支持这个命令了,现在分为两步进行
Python manage.py makemigrations [appname]
这步相当生成数据库操作日志,在创建app时在文件夹下会自动生成migrations文件夹,当数据库文件model.py发生变化后,执行这个命令都会在这个文件夹内生成一个同步的文件表明对数据库做了什么样的操作。这样方便数据恢复。
Python manage.py migrate [appname]
这一步就是数据库同步操作,执行后会根据上一步生成的文件记录对数据库进行相应的操作,当然这中间经历了比如转化sql语句等操作,我们不需要过多了解这其中细节,django会为我们自动完成
其他数据命令:
Python manage.py flush 清除数据库中的数据
Python manage.py dbshell 进入sql语句交互
Python manage.py sqlmigrate appname migrate_num 显示对应日志表的sql语句
Python manage.py inspectdb >filename 将数据库以数据模型类的形式生成代码导入到某个文件
更多命令使用:https://docs.djangoproject.com/en/1.8/ref/django-admin/
当数据库的同步操作完成后可以进入数据库查看数据表发现就有我们在模型中所写的类对应的数据表了。除此之外还有一些表并不是我们写的。这是系统为我们自动生成的一些功能表。在settings中我们使用了系统自动提供的模块的引入才会产生这些数据表,具体声明在INSTALLED_APPS中,我们也可以根据自己的需求选择留下哪些表。
INSTALLED_APPS= [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog'
]
数据库表结构修改
表结构修改后,原来表中已存在的数据,就会出现结构混乱,在以前的django版本中比较麻烦。新版本的django解决了这个问题。在models更新后直接使用上面我们学习的命令进行同步即可。但是需要注意:
1、新增加的字段,设置允许为空。生成表的时候,之前数据新增加的字段就会为空。(null=True允许数据库中为空,blank=True允许admin后台中为空)
2、新增加的字段,设置一个默认值。生成表的时候,之前的数据新增加字段就会应用这个默认值
数据操作
这里先介绍数据的增删改查操作。这个操作一般在veiws文件中完成,即达到对数据库操作的目的。
增
models.UserInfo.objects.create(user='lvze',pwd='123')
或者
obj = models.UserInfo(user='lvze',pwd='123')
obj.save()
或者
dic = {'user':'lvze','pwd':'123'}
models.UserInfo.objects.create(**dic)
删
models.UserInfo.objects.filter(user='lvze').delete()
改
models.UserInfo.objects.filter(user='lvze').update(pwd='321')
或者
obj = models.UserInfo.objects.get(user='lvze')
obj.pwd = '321'
obj.save()
查
models.UserInfo.objects.all()
models.UserInfo.objects.all().values('user') #只取user列
models.UserInfo.objects.all().values_list('id','user') #取出id和user列,并生成一个列表
models.UserInfo.objects.get(id=1)
models.UserInfo.objects.get(user='lvze')
或者我们还可以用filter查找,进行更丰富的匹配。filter查找的常用匹配方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # 获取个数 # # models.Tb1.objects.filter(name='seven').count() # 大于,小于 # # models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值 # models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值 # models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取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 # contains # # models.Tb1.objects.filter(name__contains="ven") # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感 # models.Tb1.objects.exclude(name__icontains="ven") # range # # models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and # 其他类似 # # startswith,istartswith, endswith, iendswith, # order by # # models.Tb1.objects.filter(name='seven').order_by('id') # asc # models.Tb1.objects.filter(name='seven').order_by('-id') # desc # limit 、offset # # models.Tb1.objects.all()[10:20] # group by from django.db.models import Count, Min, Max, Sum # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num')) # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id" |