python数据模型搭建_python之路(19)django数据库模型(model)
前言
object relation mapping(ORM)關(guān)系對象映射表,一個(gè)類實(shí)例映射為一條表記錄
目錄
數(shù)據(jù)庫配置
1.django?默認(rèn)使用sqlite的數(shù)據(jù)庫,如果需要使用mysql數(shù)據(jù)庫,就需要在settings中修改配置信息
DATABASES ={'default': {'ENGINE': 'django.db.backends.mysql','NAME' : '', #你的數(shù)據(jù)庫的名字
'USER' : '', #你的數(shù)據(jù)庫用戶
'PASSWORD' : '', #你的數(shù)據(jù)庫密碼
'HOST' : '', #你的數(shù)據(jù)庫主機(jī),默認(rèn)localhost
'PORT' : '3306', #你的數(shù)據(jù)庫端口
}
}
mysql數(shù)據(jù)庫配置信息
2.需要手動(dòng)導(dǎo)入PyMySQL,在_init_.py中導(dǎo)入
import MySQLdb
#注:如果想要顯示表執(zhí)行的sql語句,就在settings中配置
LOGGING={'version': 1,'disable_existing_loggers': False,'handlers': {'console':{'level':'DEBUG','class':'logging.StreamHandler',
},
},'loggers': {'django.db.backends': {'handlers': ['console'],'propagate': True,'level':'DEBUG',
},
}
}
創(chuàng)建類
1. 在models.py中創(chuàng)建類映射表
from django.db importmodels#Create your models here.
classBook(models.Model):
name=models.CharField(max_length=20)
price=models.FloatField()
pub_date=models.DateField()
publish= models.ForeignKey("Publish", on_delete=models.CASCADE) #一對多
authors = models.ManyToManyField("Author") #多對多
def __str__(self):returnself.nameclassPublish(models.Model):
name=models.CharField(max_length=32)
city=models.CharField(max_length=32)def __str__(self):returnself.nameclassAuthor(models.Model):
name= models.CharField(max_length=32)
age= models.IntegerField(default=20)def __str__(self):return self.name
2.在終端中輸入?python manage.py makemigrations?,?python manage.py migrate?兩條命令
類屬性進(jìn)階操作
classUserInfo(models.Model):
age=CharFiled(是否為空,類型,長度,列名,索引,錯(cuò)誤提示,自定義驗(yàn)證規(guī)則)
...
...
字段參數(shù)
null 數(shù)據(jù)庫中字段是否可以為空
db_column 數(shù)據(jù)庫中字段的列名
default 數(shù)據(jù)庫中字段的默認(rèn)值
primary_key 數(shù)據(jù)庫中字段是否為主鍵
db_index 數(shù)據(jù)庫中字段是否可以建立索引
unique 數(shù)據(jù)庫中字段是否可以建立唯一索引(用于一對一)
unique_for_date 數(shù)據(jù)庫中字段【日期】部分是否可以建立唯一索引
unique_for_month 數(shù)據(jù)庫中字段【月】部分是否可以建立唯一索引
unique_for_year 數(shù)據(jù)庫中字段【年】部分是否可以建立唯一索引
verbose_name Admin中顯示的字段名稱
blank Admin中是否允許用戶輸入為空
editable Admin中是否可以編輯
help_text Admin中該字段的提示信息
choices Admin中顯示選擇框的內(nèi)容,用不變動(dòng)的數(shù)據(jù)放在內(nèi)存中從而避免跨表操作
如:gf= models.IntegerField(choices=[(0, 'chen'),(1, 'xiaoyi'),],default=1)
error_messages 自定義錯(cuò)誤信息
字典健:null, blank, invalid, invalid_choice, unique,andunique_for_date
如:{'null': "不能為空.", 'invalid': '格式錯(cuò)誤'}
單表操作
-----------增#單表
#添加方法一
b = Book(name="python基礎(chǔ)",price=99,author="chen",pub_date="2017-12-12")
b.save()#添加方法二
Book.objects.create(name="PHP基礎(chǔ)",price=70,author="chen",pub_date="2016-12-12")-----------刪#單表
Book.objects.filter(author="liu").delete()-----------改#單表
Book.objects.filter(author="chen").update(price=100)-----------查#單表
book_list =Book.objects.all()print(book_list[0])
book_list= Book.objects.all()[::-2]
book_list= Book.objects.all()[::2]
book_list=Book.objects.first()
book_list=Book.objects.last()
book_list= Book.objects.get(id=4) #只能取出一條記錄的時(shí)候不報(bào)錯(cuò)
ret = Book.objects.filter(author="chen").values("name","price") #以字典的形式顯示
ret = Book.objects.filter(author="chen").values_list("name","price") #以元組的形式顯示
book_list = Book.objects.exclude(author="chen").values("name","price") #除了chen以外的人的數(shù)據(jù)
book_list = Book.objects.all().values("name").distinct() #根據(jù)一個(gè)字段去重
ret = Book.objects.all().values("name").distinct().count() #根據(jù)一個(gè)字段去重
Book.objects.filter(authors__id__in=[1,2]) #獲取id等于1或2的數(shù)據(jù)
Book.objects.filter(authors__id__range=[1,2]) #范圍
#萬能的__
#價(jià)格大于50的數(shù)/85.41
book_list = Book.objects.filter(price__gt=50).values("name","price")#模糊查詢
book_list = Book.objects.filter(name__icontains="P").values("name","price")
一對多(外鍵)
外鍵關(guān)系及參數(shù)
ForeignKey(ForeignObject)
to, 要進(jìn)行關(guān)聯(lián)的表名
to_field=None, 要關(guān)聯(lián)的表中的字段名稱
on_delete=None, 當(dāng)刪除關(guān)聯(lián)表中的數(shù)據(jù)時(shí),當(dāng)前表與其關(guān)聯(lián)的行的行為-models.CASCADE,刪除關(guān)聯(lián)數(shù)據(jù),與之關(guān)聯(lián)也刪除(常用)-models.DO_NOTHING,刪除關(guān)聯(lián)數(shù)據(jù),引發(fā)錯(cuò)誤IntegrityError-models.PROTECT,刪除關(guān)聯(lián)數(shù)據(jù),引發(fā)錯(cuò)誤ProtectedError-models.SET_NULL,刪除關(guān)聯(lián)數(shù)據(jù),與之關(guān)聯(lián)的值設(shè)置為null(前提FK字段需要設(shè)置為可空)-models.SET_DEFAULT,刪除關(guān)聯(lián)數(shù)據(jù),與之關(guān)聯(lián)的值設(shè)置為默認(rèn)值(前提FK字段需要設(shè)置默認(rèn)值)
related_name=None, 反向操作時(shí),使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, 反向操作時(shí),使用的連接前綴,用于替換【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to=None, 在Admin或ModelForm中顯示關(guān)聯(lián)數(shù)據(jù)時(shí),提供的條件:
如:- limit_choices_to={'nid__gt': 5}- limit_choices_to=lambda : {'nid__gt': 5}
db_constraint=True 是否在數(shù)據(jù)庫中創(chuàng)建外鍵約束
parent_link=False 在Admin中是否顯示關(guān)聯(lián)數(shù)據(jù)
書籍和出版社是一對多的關(guān)系
classBook(models.Model):
name=models.CharField(max_length=20)
price=models.FloatField()
pub_date=models.DateField()
publish= models.ForeignKey("Publish", on_delete=models.CASCADE) #一對多
def __str__(self):returnself.nameclassPublish(models.Model):
name=models.CharField(max_length=32)
city=models.CharField(max_length=32)def __str__(self):return self.name
添加數(shù)據(jù)的方法
#多表添加
Book.objects.create(name="linux運(yùn)維",price=77,pub_date="2017-12-12",publish_id=2)
Book.objects.create(name="GO",price=23,pub_date="2017-05-12",publish=publish_obj)
多表查詢的方法
#含外鍵:一對多查詢
#查詢?nèi)嗣癯霭嫔绯鲞^的所有書籍名字和價(jià)格
#方式一:
pub_obj=Publish.objects.filter(name="人民出版社")[0]
ret=Book.objects.filter(publish=pub_obj).values("name","price")#方式二
pub_obj = Publish.objects.filter(name="人民出版社")[0]print(pub_obj.book_set.all().values("name","price")) #book_set
print(type(pub_obj.book_set.all()))#方式三,用__
ret=Book.objects.filter(publish__name="人民出版社").values("name","price")#python基礎(chǔ)書出版社的名字
#法一
ret = Publish.objects.filter(book__name="Python基礎(chǔ)").values("name")#法二
ret3=Book.objects.filter(name="python基礎(chǔ)").values("publish__name")#北京出版出版的所有的書
ret = Book.objects.filter(publish__city="北京").values("name")
ret= Publish.objects.filter(city="北京")
一對一(外鍵+unique)
classBook(models.Model):
name=models.CharField(max_length=20)
price=models.FloatField()
pub_date=models.DateField()
publish=models.ForeignKey(
to= "Publish",
on_delete=models.CASCADE,
unique=True,
)#一對一
def __str__(self):returnself.nameclassPublish(models.Model):
name=models.CharField(max_length=32)
city=models.CharField(max_length=32)def __str__(self):return self.name
多對多(關(guān)系表)
多對多關(guān)系及參數(shù)
ManyToManyField(RelatedField)
to, 要進(jìn)行關(guān)聯(lián)的表名
related_name=None, 反向操作時(shí),使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, 反向操作時(shí),使用的連接前綴,用于替換【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to=None, 在Admin或ModelForm中顯示關(guān)聯(lián)數(shù)據(jù)時(shí),提供的條件:
如:- limit_choices_to={'nid__gt': 5}- limit_choices_to=lambda : {'nid__gt': 5}
symmetrical=None, 僅用于多對多自關(guān)聯(lián)時(shí),symmetrical用于指定內(nèi)部是否創(chuàng)建反向操作的字段#可選字段有:code, id, m1
classBB(models.Model):
code= models.CharField(max_length=12)
m1= models.ManyToManyField('self',symmetrical=True)#可選字段有: bb, code, id, m1
classBB(models.Model):
code= models.CharField(max_length=12)
m1= models.ManyToManyField('self',symmetrical=False)
through=None, 自定義第三張表時(shí),使用字段用于指定關(guān)系表
through_fields=None, 自定義第三張表時(shí),使用字段用于指定關(guān)系表中那些字段做多對多關(guān)系表from django.db importmodelsclassPerson(models.Model):
name= models.CharField(max_length=50)classGroup(models.Model):
name= models.CharField(max_length=128)
members=models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)classMembership(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, 是否在數(shù)據(jù)庫中創(chuàng)建外鍵約束
db_table= None, 默認(rèn)創(chuàng)建第三張表時(shí),數(shù)據(jù)庫中表的名稱
書籍和作者是多對多的關(guān)系
注:使用authors = models.ManyToManyField("Author"),會(huì)自動(dòng)創(chuàng)建book_authors表,也可以自己創(chuàng)建關(guān)系表(不會(huì)有authors屬性)classBook(models.Model):
name=models.CharField(max_length=20)
price=models.FloatField()
pub_date=models.DateField()
authors= models.ManyToManyField("Author") #多對多
def __str__(self):returnself.nameclassAuthor(models.Model):
name= models.CharField(max_length=32)
age= models.IntegerField(default=20)def __str__(self):return self.name
-----------增#綁定多表關(guān)系
book_obj = Book.objects.get(id=4)
authors_objs= Author.objects.get(id=2) #authors_objs = Author.objects.all()
book_obj.authors.add(authors_objs)-----------查#多對多的關(guān)系,第三張表關(guān)系表
#通過對象的方式綁定關(guān)系
#書找作者
book_obj=Book.objects.get(id=3)print(book_obj.authors.all())#作者找書
author_obj = Author.objects.get(id=2)print(author_obj.book_set.all())return HttpResponse("添加成功")-----------刪#解除多表關(guān)系
book_obj = Book.objects.get(id=4)
authors_objs= Author.objects.all() #是列表
book_obj.authors.remove(*authors_objs)
book_obj.authors.remove(2) #刪除的是數(shù)量
#清空
book_obj.authors.clear()-----------改#修改的set()方法
book_obj = Book.objects.get(id=4)
book_obj.authors.set([2,3])
手動(dòng)創(chuàng)建的多表關(guān)系
#手動(dòng)創(chuàng)建關(guān)系表
classBook(models.Model):
name=models.CharField(max_length=20)
price=models.FloatField()
pub_date=models.DateField()def __str__(self):returnself.nameclassBook_Author(models.Model):
book=models.ForeignKey("Book",on_delete=models.CASCADE)
author=models.ForeignKey("Author",on_delete=models.CASCADE)classAuthor(models.Model):
name= models.CharField(max_length=32)
age= models.IntegerField(default=20)def __str__(self):return self.name
-----------增#手動(dòng)創(chuàng)建的關(guān)系表
Book_Author.objects.create(book_id=2,author_id=3)-----------查#關(guān)聯(lián)查詢,查找書的所有作者
obj = Book.objects.get(id=2)print(obj.book_author_set.all()[0].author)#chen出過的書和價(jià)格
ret = Book.objects.filter(book_author__author__name="chen").values("name","price")
手動(dòng)創(chuàng)建的表因?yàn)闆]有第三張的字段,因此沒有自動(dòng)創(chuàng)建的表查詢的方便,而自動(dòng)創(chuàng)建的表默認(rèn)只有三個(gè)字段
因此引入? ?手動(dòng)+自動(dòng)聯(lián)合創(chuàng)建表
classUser(models.Model):
username= models.CharField(max_length=32,db_index=True)def __str__(self):returnself.usernameclassTag(models.Model):
title= models.CharField(max_length=16)
m=models.ManyToManyField(
to='User',
through='UserToTag',
through_fields=['u','t']
)def __str__(self):returnself.title#使用ManyToManyField只能在第三張表中創(chuàng)建三列數(shù)據(jù)
classUserToTag(models.Model):#nid = models.AutoField(primary_key=True)
u = models.ForeignKey(to='User')
t= models.ForeignKey(to='Tag')
ctime=models.DateField()#用于關(guān)系表u,t兩個(gè)字段共同約束唯一
classMeta:
unique_together=[
('u','t'),
]
自關(guān)聯(lián)
用戶粉絲互相關(guān)注(在同一張用戶表里,用戶互相關(guān)聯(lián))
classUser(models.Model):
username= models.CharField(max_length=32,db_index=True)
d= models.ManyToManyField('User',related_name='b')def __str__(self):return self.username
注:自關(guān)聯(lián)的跨表查詢
symmetrical=None, 僅用于多對多自關(guān)聯(lián)時(shí),symmetrical用于指定內(nèi)部是否創(chuàng)建反向操作的字段#可選字段有:code, id, m1
classBB(models.Model):
code= models.CharField(max_length=12)
m1= models.ManyToManyField('self',symmetrical=True)#可選字段有: bb, code, id, m1
classBB(models.Model):
code= models.CharField(max_length=12)
m1= models.ManyToManyField('self',symmetrical=False)
聚合函數(shù),Q函數(shù),F函數(shù)
先導(dǎo)入模塊
from django.db.models importMin,Avg,Max,Sumfrom django.db.models import F,Q
#聚合函數(shù)(需要先導(dǎo)入函數(shù))
ret = Book.objects.all().aggregate(Avg("price"))
ret= Book.objects.all().aggregate(chen_money = Sum("price")) #取別名
#查各個(gè)作者的書的價(jià)格總和
value:按照作者名字分組
ret= Book.objects.values("authors__name").annotate(Sum("price"))print(ret)#查各個(gè)出版社出的書的最小
ret = Publish.objects.values("name").annotate(Min("book__price"))print(ret)#-----------------------------------------------------------------------------------------------------------------------------
#F查詢和Q查詢,(使用前要導(dǎo)入模塊)#F拿到的值
Book.objects.all().update(price=F("price")+10)#Q可以做or操作 ,~Q表示非
re = Book.objects.filter(Q(price=80) | Q(name="GO"))#組合查詢
re = Book.objects.filter(Q(name__contains="G"))#Q查詢和關(guān)鍵字查詢組合,Q要在前面
re = Book.objects.filter(Q(name="GO"),price=80)
惰性取值,迭代對象,exists()函數(shù)
#只有在使用ret使用的時(shí)候才去查詢,惰性取值
re = Book.objects.filter(price=80) #不會(huì)取值
for i in re: #使用時(shí)才會(huì)去查詢
print(i)print(re)#---------------------------------------------------------------------
#exists()
re = Book.objects.filter(price=80)
re.exists()#會(huì)查詢,但re不會(huì)被賦值,只有使用re變量的時(shí)候才會(huì)被賦值
#----------------------------------------------------------------------
#iterator() 迭代器對象
ret = Book.objects.filter(price=80)
ret= ret.iterator()
總結(jié)
以上是生活随笔為你收集整理的python数据模型搭建_python之路(19)django数据库模型(model)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tcount在哪个文件里_在cad中tc
- 下一篇: python的函数的对象属性_Pytho