问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

django中的models有什么用

发布网友 发布时间:2022-05-02 11:56

我来回答

2个回答

懂视网 时间:2022-05-02 16:17

一、使用django orm的准备操作。
django 默认支持sqlite,mysql, oracle,postgresql数据库。
在默认情况下django的项目中会默认使用sqlite数据库,在打开settings里有如下设置:
技术分享图片

当我们想改为mysql数据库时,需要在settings.py中做以下修改。
DATABASES = {
‘default‘: {
‘ENGINE‘: ‘django.db.backends.mysql‘,
‘NAME‘: ‘test_db‘, #数据库名称
‘USER‘: ‘root‘, #连接mysql时使用的用户名
‘PASSWORD‘: ‘123456‘, #连接mysql使用的密码
‘HOST‘: ‘127.0.0.1‘, #mysql的ip
‘PORT‘: ‘3306‘, #连接mysql的端口。
}
}

当我们把连接数据的配置设置完成后,重新启动django项目,这时会报错!
no module named MySQLdb
这是因为django默认你导入的操作mysql的模块是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的模块是PyMySQL。

那么如何解决呢?
首先,要找到项目目录下的init.py文件。
然后在这个文件里面写两行代码:
import pymysql
pymysql.install_as_MySQLdb()
然后,这个报错就会解决。
(如果依旧报错。。。请检查你的pymsql是否有安装。。。)

二、在表(模型)创建之前,需要了解的概念。
首先我们先来假定下面这些概念,字段和关系。

(1)一对一关系:
假如说,一个数据库有两张表,其中一个表是作者的名字,另外一张表则是作者的详细信息。
第一张表中保存有作者的姓名,第二张表则保存了,作者的详细信息,性别,年龄,email等。
在这里,作者的名字和作者的详细信息就是一种一对一的关系,所以说,这种一对一的关系也没必要拆分成两张表。

(2)多对多关系:
拿出版商进行举例,假如说出版商的数据在一张表中,这里面包含出名称,地址,所在城市,省,国家和网站。
书籍信息中包含的书名和出版日期,但是一本书,可能会有多个作者,但是一个作者又可以写多本书。
所以说,多对多的关系就好像作者与书籍之间的关系。

(3)一对多关系:
比如一本书只能被一个出版商出版,但是一个出版商可以出版很多本书,所以说,书籍对出版商来说,就是一对多关系。
这种一对多的关系,也被称为外键。

三、关于表的创建。
models.py
class UserGroup(models.Model):
uid = models.AutoField(primary_key=True)
caption = models.CharField(max_length=32,unique=True)
ctime = models.DateTimeField(auto_now_add=True, null=True)
uptime = models.DateTimeField(auto_now=True, null=True)

class UserInfo(models.Model):

id列,自增,主键

# 用户名列,字符串类型,指定长度
# 字符串、数字、时间、二进制
username = models.CharField(max_length=32,blank=True,verbose_name=‘用户名‘)
password = models.CharField(max_length=60, help_text=‘pwd‘)
email = models.CharField(max_length=60)
test = models.EmailField(max_length=19,null=True,error_messages={‘invalid‘: ‘请输入密码‘})
#user_group_id 数字
user_group = models.ForeignKey("UserGroup",to_field=‘uid‘) # (uid,catption,ctime,uptimew)
user_type_choices = (
 (1, ‘超级用户‘),
 (2, ‘普通用户‘),
 (3, ‘访客‘),
)
user_type_id = models.IntegerField(choices=user_type_choices,default=1)

上面这段代码,每个数据模型都是django.db.models.Model的子类,它的父类Model包含了所有必要的和数据库交互的方法。
其次每个模型相当于单个数据库表(多对多关系例外,会多生成一张关系表),每个属性也是这个表中的字段。属性名就是字段名,它的类型(例如CharField)相当于数据库的字段类型(例如varchar)。大家可以留意下其它的类型都和数据库里的什么字段对应。

然后在仔细思考下,前面说的到的三种关系:
分别是一对一,一对多,多对多。
一对一:实现一对一的本质,就是在外键,(author_id就是foreign key)的关系基础上,给外键加了一个UNIQUE=True的属性;

一对多:就是主外键关系;(foreign key)

多对多:自动创建第三张表(当然我们也可以自己创建第三张表:两个foreign key。

四、orm之基本的增删改查。
(1)增:
from app01.models import *

#create方式一: Author.objects.create(name=‘kodakumi‘)

#create方式二: Author.objects.create(**{"name":"hamasakiayumi"})

!!注意!当使用到mysql innodb的事物特性的时候,就要使用save的方式插入记录了。!!

#save方式一: author=Author(name="amuro")
author.save()

#save方式二: author=Author()
author.name="amuro"
author.save()

(2)删:
models.UserInfo.objects.filter(username="amuro").delete()

(3)改:
models.UserInfo.objects.filter(id=3).update(password="130")

--------------- save方法---------
obj=models.UserInfo.objects.filter(id=3)[0]
obj.password = ‘130‘
obj.save()

(4)查:

#result = models.UserInfo.objects.all() #列出表所有记录,返回一个QuerySet类型。

!!在这里简单介绍一下什么是Queryset类型!
在这里,我们可以把Queryset理解为一个列表,这个列表中有很多对象,每个对象就是数据库中的每一条数据!!

#result = models.UserInfo.objects.filter(username=‘root‘,password=‘123‘) #按条件查询
 查询相关API如下:
 【1】filter(**kwargs): 它包含了与所给筛选条件相匹配的对象。
 filter方法的参数补充:
 #在这以age列做例子:
 age_gt = 1 #age大于1的。
 age_lt = 1 #age小于1的。
 age_lte = 1 #age小于等于1
 age_gte = 1 #age大于等于1
 age_in = [1,2,3] # 找出age为1或2或3的(只要列表中有的就可以)
 age_range = [1,2]#age为这个范围的。
 age_startwith = ‘xxx‘ #age列以xxx开头的
 age_contains = ‘xxx‘ #包含xxx的。
 【2】all():   查询所有结果。
 【3】get(**kwargs):  返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。

#===============================#
下面是对查询结果进行处理的API
【1】values(field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列.
需要特别注意!!values这个方法可以用来分组!!

values 可以取表中所有记录中的某一个或多个列的数据。
例如:
v1 = models.UserInfo.objects.values(‘name‘) #select UserInfo.name from UserInfo
print (v1.query) #获取到生成的sql语句。
select app01_UserInfo.name from UserInfo

!!通过values方法然后通过.annotate进行组合!
from django.db.models import Count
v2 = models.UserInfo.objects.values(‘name‘).annotate(count_num=Count(‘id‘))
print (v2.query)
#select ‘app01_UserInfo‘.‘id‘,COUNT(‘app01_UserInfo‘.id) as "count_num" from "app01_UserInfo" group by ‘app01_UserInfo‘.id‘

!!组合后的查询结果,还可以通过filter方法来进行筛选!

from django.db.models import Count
v2=models.UserInfo.objects.values(‘name‘).annotate(count_num=Count(‘id‘)).filter(count_num = 2)
!#筛选出count_num = > 2 的记录。
print (v2.query)
#select ‘app01_UserInfo‘.‘id‘,COUNT(‘app01_UserInfo‘.id) as "count_num" from "app01_UserInfo" group by ‘app01_UserInfo‘.id‘ having count (‘app01_UserInfo‘.id‘)> 2
#!也就是说把filter放在后面,出现的是sql语句中的having!!

【2】order_by(*field): 对查询结果排序。
例:
user_list = models.UserInfo.objects.all().order_by(‘id‘) #以id列为基准从小到大排序。
user_list = models.UserInfo.objects.all().order_by(‘-id‘) #以id列为基准从大到小逆向排序。
 user_list = models.UserInfo.objects.all().order_by(‘-id‘,‘name‘) #以id列为基准从大到小逆向排序,当id列有值重复时,按照name从小到大排序。

【3】reverse() :对查询的结果进行反向排序。
【4】distinct(): 从结果中删除重复的记录。
【5】values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列。
【6】count(): 返回数据库中匹配查询(QuerySet)的对象数量。
【7】first(): 返回第一条记录
【8】last(): 返回最后一条记录
【9】exists(): 如果QuerySet包含数据,就返回True,否则返回False。

单表条件查询:
models.Tb1.objects.filter(id=10,name=‘test‘) #找出id=10 并且name字段为test的记录 。
!########下面是神奇的双(下划线)!########
models.Tb1.objects.filter(idlt=10, idgt=1) # 获取id大于1 且 小于10的值
models.Tb1.objects.filter(idin=[11, 22, 33]) # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in

是否为空:
Entry.objects.filter(pub_date__isnull=True)

五、通过外键来实现一对多的示例:
models.py
class Business(models.Model):
#id
caption = 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=‘ipv4‘,db_index=True)
port = models.IntegerField()
busi = models.ForeignKey(to=‘Business‘,to_field=‘id‘)#创建外键,这个外键以表Business的id字段为准。
不过需要注意的是,这个busi变量的内容不是某个值,而是一个特殊对象,可以通过这个对象去取到Business表中对应id的记录。!!

当创建好外键关系后,在 Business表中插入了三条数据:
+----+-----------+
| id | caption |
+----+-----------+
| 1 | 运维部 |
| 2 | 开发部 |
| 3 | 测试部 |
+----+-----------+

然后在host表中插入四条主机信息:
+-----+----------+---------------+------+---------+
| nid | hostname | ip | port | busi_id |
+-----+----------+---------------+------+---------+
| 1 | host1 | 192.168.100.1 | 80 | 1 |
| 2 | host2 | 192.168.100.5 | 80 | 1 |
| 3 | host3 | 192.168.100.6 | 80 | 2 |
| 4 | host4 | 192.168.100.7 | 80 | 2 |
+-----+----------+---------------+------+---------+

这时,使用django orm进行联表查询:
views.py:

def host(request):
h1 = models.Host.objects.all()
for row in h1:
print(row.nid,row.hostname,row.ip,row.busi.caption)
return HttpResponse(‘host‘)
#busi 带只了另外一张表的一行数据,这就是外键的特性!
结果如下:
1 host1 192.168.100.1 运维部
2 host2 192.168.100.5 运维部
3 host3 192.168.100.6 开发部
4 host4 192.168.100.7 开发部

六、关于F,Q
F:当要对数据库记录做修改的时候,能快速获取到上一个值,来进行操作。
比如:
models.UserInfo.objects.all().update(age=F(‘age‘)+1)

Q:用于复杂的条件查询,Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询。可以组合使用 &(and),|(or),~(not)操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。
例如:
用法1:
models.UserInfo.objects.filter(Q(id=1)|Q(id__gt=2))
##查找出id为1或者2的记录。

用法2:直接创建一个Q对象。
q1 = Q( ) #首先创建一个Q对象。
q1.connector = ‘OR‘ #Q对象中的查询条件的连接方式。
q1.children.append((‘id‘,1))
q1.children.append((‘id‘,2)) #在Q1这个对象里添加两个查询条件。

更复杂的条件嵌套。
q1 = Q( )
q1.connector = ‘OR‘
q1.children.append((‘id‘,1))
q1.children.append((‘id‘,2))

q2 = Q( )
q2.connector = ‘OR‘
q2.children.append((‘name‘,‘ayu‘))
q2.children.append((‘name‘,‘hamasaki‘))

con = Q( )
con.add(q1,‘AND‘)
con.add(q2,‘AND‘)
#最后生成的结果是(id=1 or id=2) and (name=ayu or name=hamasaki)

13.Django之数据库models&orm初探(一)

标签:imp   情况下   思考   修改   sql数据库   prim   mod   distinct   view   

热心网友 时间:2022-05-02 13:25

model的作用是定义出对象模型,一般都是和数据库里表对应,一个表一个model类,表里面的字段对应model类的属性,
这其实是MVC思想中的M的model层
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
!这叫什么号 百万医疗赔付后是否可以续保 前一年理赔过医疗险还能续保吗? 医疗住院险理赔后还能购买吗? 女生多大后可以不在长身高? 如何不用软件把手机投屏到电脑上手机屏幕怎样投放到电脑上 战时拒绝、故意延误军事订货罪既遂的处罚? 战时故意延误军事订货罪处罚标准 名师1+1导读方案:汤姆·索亚历险记目录 三星sm-g7200打开微信慢,无法正常收看,网速不慢。 温江户口在温江办身份证需要多长时间 如何将录制的视频中的背景音乐摘出来? 怎样才能辨别真玉和假玉? 84年奥运会在哪个国家 麻烦懂的朋友给看看从这打灯的图片上看,这是和田玉中的羊脂白玉的结构吗? 12年奥运会在哪举办 amd cpu 插到主板上就报警 请问是不是cpu坏了 微星a75a G35主板 AMD速龙IIX4 651 ,用gtx660开机主板报警,换另一个卡槽显 2024年奥运会在哪个国家? 微星amd主板插上采集卡黑屏开不了机了? 2024年奥运会在哪举行?? 你好 我新配置的服务器 但是启动不了 超微x9dai开机连响5声是怎么回事啊 2012年奥运会在哪举办? 主板长鸣报警 2022年奥运会在哪个国家 2022年奥运会在哪举行 图形工作站出现问题 2021年奥运会在哪个国家 开机报警 5短1长 是什么意思? 美联储今年不加息有哪些影响? FOMC会议是什么 美联储议息会议结果是什么?对美股有什么影响? 2017美联储议息会议哪里最快知道结果 历史不会说谎,美加息会对股市有多大影响 什么是美联储议息会议纪要 马上要办宽带了,有什么好的运营商可以推荐的? 拉网线,三大运营商,哪个好 拉宽带移动的好还是电信? 拉宽带哪个运营商好 django中的models.manytomanyfield是什么意思 电脑上字母windows是什么意思啊 电脑上windows是什么意思 电脑中有个:Windows是什么意思啊 电脑考试window是什么意思 Django中,Model.objects.create 和 Model 的区别 计算器上arccos怎么按 平安保单价值是什么意思 去年平安智胜人生万能保险 一年交4000,交10年,请问下10拿后现金价值多少 平安万能险里面的现金怎样提取,保费每年6000元的可以改为4000元每年吗