25.django Model
django ORM基本配置
django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表
1.修改project数据库配置
(1)settigs.py里面
默认
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
- }
- }
修改为mysql数据库:
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME': 'mysql', #数据库名字
- 'USER': 'root', #账号
- 'PASSWORD': '', #密码
- 'HOST': '192.168.43.128', #IP
- 'PORT': '', #端口
- }
- }
(2)把模块改成pymysql
修改project目录下的init.py
- import pymysql
- pymysql.install_as_MySQLdb()
2.创建数据库表结构文件
对应app目录下的models.py
(1)生成一个简单的数据库表:
- from django.db import models
- class UseInfo(models.Model):
- username = models.CharField(max_length=32)
- passwd = models.CharField(max_length=64)
- # 数据库默认创建id列 自增 主键
- # 用户名列 字符串类型 字符长度
(2)把app名称加入到settings里面
- INSTALLED_APPS = [
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'cmdb', # 系统会加载cmdb下的model.py文件
- ]
(3)执行命令生成到数据库
- python manage.py makemigrations
- python manage.py migrate # 生成数据表
3.数据库字段和字段参数
- 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 文件
- 所有字段...
字段
- null -> db是否可以为空
- default -> 默认值
- primary_key -> 主键
- db_column -> 列名
- db_index -> 索引
- unique -> 唯一索引
- unique_for_date ->
- unique_for_month
- unique_for_year
- auto_now -> 更新时,自动更新为当前时间
- auto_now_add -> 创建时,自动生成时间
- choices -> django admin中显示下拉框,避免连表查询
- blank -> django admin是否可以为空
- verbose_name -> django admin显示字段中文
- editable -> django admin是否可以被编辑
- error_messages -> 错误信息欠
- help_text -> django admin提示
- validators -> django
- form, 自定义错误信息(欠)
- 所有字段参数...
字段参数
数据库基本操作
1.增加数据
(1)最常用的方式
- from cmdb import models
- def userinfo(request):
- models.UseInfo.objects.create(username='derek',passwd='')
- return HttpResponse('这种最常用')
(2)第二种跟第一种差不多
- def userinfo(request):
- # models.UseInfo.objects.create(username='derek',passwd='666')
- # return HttpResponse('这种最常用')
- dicts = {'username':'jack','passwd':''}
- models.UseInfo.objects.create(**dicts)
- return HttpResponse('第二种跟第一种差不多')
(3)第三种
- def userinfo(request):
- obj = models.UseInfo(username='tom',passwd='')
- obj.save()
- return HttpResponse('第三种')
2.查询数据
(1)查询所有
- def select(request):
- result = models.UseInfo.objects.all()
- print(result) #QuerySetL类型
- for row in result:
- print(row.id,row.username,row.passwd)
- return HttpResponse('select')
(2)查询指定字段
- def select(request):
- result = models.UseInfo.objects.filter(username='derek')
- if result:
- for row in result:
- print(row.id,row.username,row.passwd)
- return HttpResponse('select')
3.删除数据
- def select(request):
- models.UseInfo.objects.filter(id=3).delete()
- return HttpResponse('select')
4.更新数据
- def select(request):
- models.UseInfo.objects.filter(id=2).update(passwd='')
- return HttpResponse('select')
数据库一对多操作
1.数据表结构
- from django.db import models
- class UseGroup(models.Model):
- uid = models.AutoField(primary_key=True) #主键,自增
- caption = models.CharField(max_length=32,unique=True) #唯一索引
- ctime = models.DateField(auto_now_add=True,null=True) #创建时生成时间
- uptime = models.DateField(auto_now=True,null=True) #更新时自动更新时间
- class UseInfo(models.Model):
- username = models.CharField(max_length=32)
- passwd = models.CharField(max_length=64)
- # 关联外键,生成字段名为user_group_id
- user_group = models.ForeignKey("UseGroup",to_field="uid",default=1)
2.外键关联添加数据
- from django.shortcuts import render,HttpResponse
- from app01 import models
- def add(request):
- ug_obj = models.UseGroup.objects.create(caption = "外键数据添加")
- # 把外键ug_obj当参数传入
- models.UseInfo.objects.create(username='derek',passwd='',user_group=ug_obj)
- return HttpResponse('')
3.外键关联表操作
- from django.shortcuts import render,HttpResponse
- from app01 import models
- # def add(request):
- # ug_obj = models.UseGroup.objects.create(caption = "外键数据添加")
- # # 把外键ug_obj当参数传入
- # models.UseInfo.objects.create(username='derek',passwd='123',user_group=ug_obj)
- # return HttpResponse('11')
- def ormadd(request):
- models.UseInfo.objects.create(username='jack',passwd='')
- return HttpResponse('')
- def ormgroup(request):
- models.UseGroup.objects.create(caption='CEO')
- return HttpResponse('')
- def userinfo(request):
- obj = models.UseInfo.objects.all().first()
- print(obj.id,obj.username,obj.user_group_id)
- print(obj.user_group.uid,obj.user_group.caption)
- return HttpResponse('')
返回结果:
4.跨表查询使用双下划綫 "__"
- from django.db import models
- class Business(models.Model):
- caption = models.CharField(max_length=32)
- code = models.CharField(max_length=32,null=True,default='QA')
- class Host(models.Model):
- nid = models.AutoField(primary_key=True)
- hostname = models.CharField(max_length=32,db_index=True)
- ip = models.GenericIPAddressField(protocol='ipv4',db_index=True)
- port = models.IntegerField()
- b = models.ForeignKey(to='Business',to_field='id')
获取表单数据
- from django.shortcuts import render,HttpResponse
- from app01 import models
- def home(request):
- v2 = models.Host.objects.filter(nid=1).values('nid','hostname','b_id','b__caption')
- print(v2)
- return HttpResponse('')
- <QuerySet [{'nid': 1, 'hostname': 'c1.com', 'b_id': 1, 'b__caption': '运维'}]>
实例(一) 模板中显示数据库内容的方法
创建数据库
- from django.db import models
- from django.db import models
- class Business(models.Model):
- caption = models.CharField(max_length=32)
- code = models.CharField(max_length=32)
- class Host(models.Model):
- nid = models.AutoField(primary_key=True)
- hostname = models.CharField(max_length=32,db_index=True)
- ip = models.GenericIPAddressField(protocol='both',db_index=True)
- port = models.IntegerField()
- business = models.ForeignKey(to='Business',to_field='id',on_delete=models.CASCADE)
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>业务线列表(对象)</h1>
- <ul>
- {% for row in v1 %}
- <li>{{ row.id }}-{{ row.caption }}-{{ row.code }}</li>
- {% endfor %}
- </ul>
- <h1>业务线列表(字典)</h1>
- <ul>
- {% for row2 in v2 %}
- <li>{{ row2.id }}-{{ row2.caption }}</li>
- {% endfor %}
- </ul>
- </body>
- </html>
business.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>主机列表(对象)</h1>
- <table border="1">
- <tread>
- <tr>
- <th>主机ID</th>
- <th>IP</th>
- <th>端口</th>
- <th>业务线名称</th>
- </tr>
- </tread>
- <tbody>
- {% for row in v1 %}
- <tr>
- <td>{{ row.hostname }}</td>
- <td>{{ row.ip }}</td>
- <td>{{ row.port }}</td>
- <td>{{ row.business.caption }}</td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- <h1>主机列表(字典)</h1>
- <table border="1">
- <tread>
- <tr>
- <th>主机ID</th>
- <th>主机名</th>
- <th>业务线ID</th>
- <th>业务线名称</th>
- </tr>
- </tread>
- <tbody>
- {% for row in v2 %}
- <tr>
- <td>{{ row.nid }}</td>
- <td>{{ row.hostname }}</td>
- <td>{{ row.business__id }}</td>
- <td>{{ row.business__caption }}</td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- <h1>主机列表(元祖)</h1>
- <table border="1">
- <tread>
- <tr>
- <th>主机ID</th>
- <th>主机名</th>
- <th>业务线ID</th>
- <th>业务线名称</th>
- </tr>
- </tread>
- <tbody>
- {% for row in v3 %}
- <tr>
- <td>{{ row.0 }}</td>
- <td>{{ row.1 }}</td>
- <td>{{ row.2 }}</td>
- <td>{{ row.3 }}</td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- </body>
- </html>
host.html
- from django.shortcuts import render,HttpResponse
- from app01 import models
- def business(request):
- # 第一种方式(是个对象)
- v1 = models.Business.objects.all()
- # 第二种方式,只取id和caption(是个字典)
- v2 = models.Business.objects.all().values('id','caption')
- return render(request,'business.html',{'v1':v1,'v2':v2})
- def host(request):
- #总共三种方式,对象,字典,列表
- v1 = models.Host.objects.all()
- v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','business__id','business__caption')
- v3 = models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','business__id','business__caption')
- return render(request,'host.html',{'v1':v1,'v2':v2,'v3':v3})
实例(二) 一对多
1.创建
- from django.db import models
- class UserType(models.Model):
- title = models.CharField(max_length=32)
- class UserInfo(models.Model):
- name = models.CharField(max_length=16)
- age = models.IntegerField()
- ut = models.ForeignKey('UserType')
- from django.shortcuts import render,HttpResponse
- from app01 import models
- def add(request):
- models.UserType.objects.create(title='普通用户')
- models.UserType.objects.create(title='黄金用户')
- models.UserType.objects.create(title='白金用户')
- models.UserInfo.objects.create(name='aa', age=18, ut_id=1)
- models.UserInfo.objects.create(name='bb', age=18, ut_id=2)
- models.UserInfo.objects.create(name='cc', age=18, ut_id=2)
- return HttpResponse('ok')
2.操作
(1)查询所有用户和类型
- def op(request):
- obj = models.UserInfo.objects.all()
- for row in obj:
- print(row.name,row.age,row.ut.title)
- return HttpResponse('ok')
- #查看所有
- aa 18 普通用户
- bb 18 黄金用户
- cc 18 黄金用户
- #查看第一条
- obj = models.UserInfo.objects.all().first()
- print(obj.name, obj.age, obj.ut.title)
- aa 18 普通用户
(2)查询所有类型为“黄金用户的”用户
正向查
- #这里跨表查询要用到双下划线"__"
result = models.UserInfo.objects.filter(ut__title='黄金用户')- for item in result:
- print(item.name,item.age,item.ut.title)
- 结果:
- bb 18 黄金用户
- cc 18 黄金用户
反向查
- obj = models.UserType.objects.get(id=2)
- result = obj.userinfo_set.all()
- #这里的userinfo_set相当于models.UserInfo.objects.filter(ut="黄金用户")
- for item in result:
- print(item.name,item.age,item.ut.title)
- 结果:
- bb 18 黄金用户
- cc 18 黄金用户
还可以加条件过滤
- obj = models.UserType.objects.get(id=2)
- result = obj.userinfo_set.filter(name='bb')
- #这里的userinfo_set相当于models.UserInfo.objects.filter(ut="黄金用户")
- for item in result:
- print(item.name,item.age,item.ut.title)
- 结果:
- bb 18 黄金用户
数据库多对多操作
1.自动方式创建第三张表
(1)创建管理用户和主机两张表,自动生成第三张关系表
- from django.db import models
- class Host(models.Model):
- hostname = models.CharField(max_length=32)
- port = models.IntegerField()
- class HostAdmin(models.Model):
- username = models.CharField(max_length=32)
- email = models.CharField(max_length=32)
- host = models.ManyToManyField('Host')
(2)添加主机信息和管理用户信息
- #添加主机信息
- def add_host(request):
- models.Host.objects.create(hostname='host1',port=80)
- models.Host.objects.create(hostname='host2',port=80)
- models.Host.objects.create(hostname='host3',port=80)
- models.Host.objects.create(hostname='host4',port=80)
- return HttpResponse('ok')
- #添加管理用户信息
- def add_hostadmin(request):
- models.HostAdmin.objects.create(username='aa',email='11.com')
- models.HostAdmin.objects.create(username='bb',email='22.com')
- models.HostAdmin.objects.create(username='cc',email='33.com')
- models.HostAdmin.objects.create(username='dd',email='44.com')
- return HttpResponse('ok')
效果如下:
(3)添加第三张关系表
正向添加数据
- #添加第三张表信息,使管理用户与主机关联
- def user_info(request):
- # 第一步找到用户
- admin_obj = models.HostAdmin.objects.get(username='bb')
- #第二步找到主机
- host_list = models.Host.objects.filter(id__lt=3)
- #第三步,通过找到的admin_obj对象.add去添加主机
- admin_obj.host.add(*host_list)
- return HttpResponse('ok')
效果如下:
用户‘’bb“(用户id=2)就跟主机‘1’和‘2’(主机id=(1,2))关联起来了
反向添加数据
- def user_info(request):
- host_obj = models.Host.objects.get(id=3)
- admmin_list = models.HostAdmin.objects.filter(id__gt=1)
- host_obj.hostadmin_set.add(*admmin_list)
- return HttpResponse('ok')
效果如下:
总之,不管是正向添加还是反向添加,都是基于主机表或者用户表的一行数据对应另一张表中的一行或多行数据!
2.手动方式创建第三张表
(1)创建
手动创建就是告诉django不要自动创建表了
- from django.db import models
- class HostInfo(models.Model):
- hostname = models.CharField(max_length=32)
- port = models.IntegerField()
- class UserMap(models.Model):
- username = models.CharField(max_length=32)
- email = models.CharField(max_length=32)
- # through告诉Django用那张表做关联
- host = models.ManyToManyField(HostInfo, through='HostRelation')
- class HostRelation(models.Model):
- host = models.ForeignKey('HostInfo')
- user = models.ForeignKey('UserMap')
效果如下:
(2)添加用户和主机
- from django.shortcuts import render,HttpResponse
- from app02 import models
- def user_info(request):
- models.HostInfo.objects.create(hostname='host1',port=80)
- models.HostInfo.objects.create(hostname='host2',port=80)
- models.HostInfo.objects.create(hostname='host3',port=80)
- models.HostInfo.objects.create(hostname='host4',port=80)
- models.UserMap.objects.create(username='aa',email='11.com')
- models.UserMap.objects.create(username='bb',email='22.com')
- models.UserMap.objects.create(username='cc',email='33.com')
- models.UserMap.objects.create(username='dd',email='44.com')
- return HttpResponse('ok')
(3)给第三张表添加数据
当使用自定义方式时,第三张关系表数据直接添加就可以,不需要管另外两张表
- def user_info(request):
- models.HostRelation.objects.create(
- host_id = 2,
- user_id = 2
- )
- return HttpResponse('ok')
效果:
- models.HostRelation.objects.create(
- host_id = 1,
- user_id = 1
- )
- models.HostRelation.objects.create(
- host_id=3,
- user_id=1
- )
添加多个
(4)查找
通过自定义方式,查找直接查就可以,不存在正向反向,更方便
- def user_info(request):
- relation_list = models.HostRelation.objects.all()
- for item in relation_list:
- print(item.user.username)
- print(item.host.hostname)
- return HttpResponse('ok')
- 结果:
- bb
- host2
- aa
- host1
- aa
- host3
- def user_info(request):
- relation_list = models.HostRelation.objects.filter(user__username='bb')
- for item in relation_list:
- print(item.user.username)
- print(item.host.hostname)
- return HttpResponse('ok')
ORM的F&Q
1.F
F的作用:用来批量修改数据的
比如:把上面hostinfo表所有port从80改成90
- models.HostInfo.objects.all().update(port=F('port')+10)
要先导入模块
- from django.db.models import F
2.Q
Q的作用:Q是用来做条件查询的
25.django Model的更多相关文章
- django model数据 时间格式
from datetime import datetime dt = datetime.now() print '时间:(%Y-%m-%d %H:%M:%S %f): ' , dt.strftime( ...
- 【转】Django Model field reference学习总结
Django Model field reference学习总结(一) 本文档包含所有字段选项(field options)的内部细节和Django已经提供的field types. Field 选项 ...
- Django model字段类型清单
转载:<Django model字段类型清单> Django 通过 models 实现数据库的创建.修改.删除等操作,本文为模型中一般常用的类型的清单,便于查询和使用: AutoField ...
- Django:Model的Filter
转自:http://www.douban.com/note/301166150/ django model filter 条件过滤,及多表连接查询.反向查询,某字段的distinct 1.多表 ...
- Django model中 双向关联问题,求帮助
Django model中 双向关联问题,求帮助 - 开源中国社区 Django model中 双向关联问题,求帮助
- django 自定用户系统 以及 Django Model 定义语法
http://www.tuicool.com/articles/jMzIr2 django使用自己的用户系统 http://www.jianshu.com/p/c10be59aad7a Django ...
- tornado with MySQL, torndb, django model, SQLAlchemy ==> JSON dumped
现在,我们用torndo做web开发框架,用他内部机制来处理HTTP请求.传说中的非阻塞式服务. 整来整去,可谓之一波三折.可是,无论怎么样,算是被我做成功了. 在tornado服务上,采用三种数据库 ...
- Django Model field reference
===================== Model field reference ===================== .. module:: django.db.models.field ...
- Django model对象接口
Django model查询 # 直接获取表对应字段的值,列表嵌元组形式返回 Entry.objects.values_list('id', 'headline') #<QuerySet [(1 ...
随机推荐
- 定时执行 Job - 每天5分钟玩转 Docker 容器技术(135)
Linux 中有 cron 程序定时执行任务,Kubernetes 的 CronJob 提供了类似的功能,可以定时执行 Job.CronJob 配置文件示例如下: ① batch/v2alpha1 是 ...
- 表的操作(Oracle和DB2)
asc和desc 分别表示升序和降序 select * from tablename order by id desc :根据id字段按照降序排列,从大到小 select * from tablena ...
- angular4升级angular5问题记录之No NgModule metadata found for 'AppModule'
在将项目从angular4升级到angular5的过程中,出现No NgModule metadata found for 'AppModule'问题,网上查找答案将app.module.ts进行再次 ...
- 测试任务汇总v1.0
2017.08.04 整理了目前我们所在团队需要做的日常任务 定义为v1.0
- 老男孩Python全栈开发(92天全)视频教程 自学笔记17
day17课程内容: 装饰器回顾练习 登录功能: #登录京东,不同的页面,选择页面,然后不同的登录方式with open('作业5.1jingdong','w',encoding='utf8') as ...
- 集成 solr6.5.1到 tomcat7(8) 中 (解决java.lang.NoSuchMethodError问题)
♣下载solr安装包 ♣安装solr ♣solr应用部署到tomcat下 ♣配置web.xml ♣在tomcat7启动 ♣改为在tomcat8启动 ♣在自带的Jetty里启动 ♣建立第一个Core 安 ...
- Android ADB Server启动失败
启动Android Stdio的时候报如下错误: Unable to create Debug Bridge: Unable to start adb server: error: could not ...
- 总结JS中string、math、array的常用的方法
JS为每种数据类型都内置很多方法,真的不好记忆,而且有些还容易记混,现整理如下,以便以后查看: 一.String ①charAt()方法用于返回指定索引处的字符.返回的字符是长度为 1 的字符串. 语 ...
- nyoj222 整数中的1 数位DP
从a枚举到b是一定会超时的.此题应该考虑数位dp,也可以理解为递推,假设给定数n,就能在O(32)复杂度算出所有小于等于n的数中1出现的次数,那么给定区间[a, b],solve(b) - solve ...
- 学习笔记︱Nvidia DIGITS网页版深度学习框架——深度学习版SPSS
DIGITS: Deep Learning GPU Training System1,是由英伟达(NVIDIA)公司开发的第一个交互式深度学习GPU训练系统.目的在于整合现有的Deep Learnin ...