Django基础——ORM字段和字段参数
ORM概念:
對(duì)象關(guān)系映射(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向?qū)ο笈c關(guān)系數(shù)據(jù)庫存在的互不匹配的現(xiàn)象(
1. 不同的程序員寫的SQL水平參差不齊
2. 執(zhí)行效率也參差不齊
)的技術(shù)。
ORM 能夠把 python語句 自動(dòng)的翻譯 為SQL語句
ORM優(yōu)點(diǎn):
1. 簡單,不用自己寫SQL語句
2. 開發(fā)效率高
缺點(diǎn):
執(zhí)行效率有差距
ORM的對(duì)應(yīng)關(guān)系:
類 ---> 數(shù)據(jù)表
對(duì)象 ---> 數(shù)據(jù)行
屬性 ---> 字段
?
ORM能做的事兒:
1. 操作數(shù)據(jù)表 --> 創(chuàng)建表/刪除表/修改表
操作models.py里面的類
2. 操作數(shù)據(jù)行 --> 數(shù)據(jù)的增刪改查
不能創(chuàng)建數(shù)據(jù)庫,自己動(dòng)手創(chuàng)建數(shù)據(jù)庫
使用Django的ORM詳細(xì)步驟:
1. 自己動(dòng)手創(chuàng)建數(shù)據(jù)庫
create database 數(shù)據(jù)庫名;
2. 在Django項(xiàng)目中設(shè)置連接數(shù)據(jù)庫的相關(guān)配置(告訴Django連接哪一個(gè)數(shù)據(jù)庫)
# 數(shù)據(jù)庫相關(guān)的配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 連接的數(shù)據(jù)庫類型
'HOST': '127.0.0.1', # 連接數(shù)據(jù)庫的地址
'PORT': 3306, # 端口
'NAME': "day61", # 數(shù)據(jù)庫名稱
'USER': 'root', # 用戶
'PASSWORD': '123456' # 密碼
}
}
3. 告訴Django用pymysql代替默認(rèn)的MySQLDB 連接MySQL數(shù)據(jù)庫
在項(xiàng)目/__init__.py文件中,寫下面兩句:
import pymysql
# 告訴Django用pymysql來代替默認(rèn)的MySQLdb
pymysql.install_as_MySQLdb()
4. 在app/models.py里面定義類
# 出版社
class Publisher(models.Model):
id = models.AutoField(primary_key=True) # 自增的ID主鍵
# 創(chuàng)建一個(gè)varchar(64)的唯一的不為空的字段
name = models.CharField(max_length=64, null=False, unique=True)
5. 執(zhí)行兩個(gè)命令
1. python3 manage.py makemigrations --> 把models.py里面的更改記錄到小本本上
2. python3 manage.py migrate --> 把更改翻譯成SQL語句,去數(shù)據(jù)庫執(zhí)行
Django ORM常用字段:
1. AutoField --> 自增
2. CharField --> varchar(xx)
3. ForeignKey --> 外鍵
ForeignKey 字段的參數(shù);
a.to? --> 設(shè)置要關(guān)聯(lián)的表;
b.to_field -->設(shè)置要關(guān)聯(lián)的表的字段
c.related_name -->??反向操作時(shí),使用的字段名,用于代替原反向查詢時(shí)的'表名_set'。
4. ManyToManyField --> 多對(duì)多關(guān)聯(lián)
5. DateField? -->日期字段,日期格式? YYYY-MM-DD?
6. DateTimeField -->?日期時(shí)間字段,格式 YYYY-MM-DD HH:MM
7. IntegerField -->整數(shù)類型
?字段的合集:
AutoField(Field)- int自增列,必須填入?yún)?shù) primary_key=TrueBigAutoField(AutoField)- bigint自增列,必須填入?yún)?shù) primary_key=True注:當(dāng)model中如果沒有自增列,則自動(dòng)會(huì)創(chuàng)建一個(gè)列名為id的列from django.db import modelsclass UserInfo(models.Model):# 自動(dòng)創(chuàng)建一個(gè)列名為id的且為自增的整數(shù)列username = models.CharField(max_length=32)class Group(models.Model):# 自定義自增列nid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)SmallIntegerField(IntegerField):- 小整數(shù) -32768 ~ 32767PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)- 正小整數(shù) 0 ~ 32767IntegerField(Field)- 整數(shù)列(有符號(hào)的) -2147483648 ~ 2147483647PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)- 正整數(shù) 0 ~ 2147483647BigIntegerField(IntegerField):- 長整型(有符號(hào)的) -9223372036854775808 ~ 9223372036854775807BooleanField(Field)- 布爾值類型NullBooleanField(Field):- 可以為空的布爾值CharField(Field)- 字符類型- 必須提供max_length參數(shù), max_length表示字符長度TextField(Field)- 文本類型EmailField(CharField):- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證機(jī)制IPAddressField(Field)- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證 IPV4 機(jī)制GenericIPAddressField(Field)- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證 Ipv4和Ipv6- 參數(shù):protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"unpack_ipv4, 如果指定為True,則輸入::ffff:192.0.2.1時(shí)候,可解析為192.0.2.1,開啟此功能,需要protocol="both"URLField(CharField)- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證 URLSlugField(CharField)- 字符串類型,Django Admin以及ModelForm中提供驗(yàn)證支持 字母、數(shù)字、下劃線、連接符(減號(hào))CommaSeparatedIntegerField(CharField)- 字符串類型,格式必須為逗號(hào)分割的數(shù)字UUIDField(Field)- 字符串類型,Django Admin以及ModelForm中提供對(duì)UUID格式的驗(yàn)證FilePathField(Field)- 字符串,Django Admin以及ModelForm中提供讀取文件夾下文件的功能- 參數(shù):path, 文件夾路徑match=None, 正則匹配recursive=False, 遞歸下面的文件夾allow_files=True, 允許文件allow_folders=False, 允許文件夾FileField(Field)- 字符串,路徑保存在數(shù)據(jù)庫,文件上傳到指定目錄- 參數(shù):upload_to = "" 上傳文件的保存路徑storage = None 存儲(chǔ)組件,默認(rèn)django.core.files.storage.FileSystemStorageImageField(FileField)- 字符串,路徑保存在數(shù)據(jù)庫,文件上傳到指定目錄- 參數(shù):upload_to = "" 上傳文件的保存路徑storage = None 存儲(chǔ)組件,默認(rèn)django.core.files.storage.FileSystemStoragewidth_field=None, 上傳圖片的高度保存的數(shù)據(jù)庫字段名(字符串)height_field=None 上傳圖片的寬度保存的數(shù)據(jù)庫字段名(字符串)DateTimeField(DateField)- 日期+時(shí)間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]DateField(DateTimeCheckMixin, Field)- 日期格式 YYYY-MM-DDTimeField(DateTimeCheckMixin, Field)- 時(shí)間格式 HH:MM[:ss[.uuuuuu]]DurationField(Field)- 長整數(shù),時(shí)間間隔,數(shù)據(jù)庫中按照bigint存儲(chǔ),ORM中獲取的值為datetime.timedelta類型FloatField(Field)- 浮點(diǎn)型DecimalField(Field)- 10進(jìn)制小數(shù)- 參數(shù):max_digits,小數(shù)總長度decimal_places,小數(shù)位長度BinaryField(Field)- 二進(jìn)制類型字段合集
在ORM 表單中沒有char字段;需要自定義
#自定義char字段 class FixedCharField(models.Field):"""自定義的char類型的字段類"""def __init__(self, max_length, *args, **kwargs):self.max_length = max_lengthsuper(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs)def db_type(self, connection):"""限定生成數(shù)據(jù)庫表的字段類型為char,長度為max_length指定的值"""return 'char(%s)' % self.max_length class Class(models.Model):id = models.AutoField(primary_key=True)title = models.CharField(max_length=25)# 使用上面自定義的char類型的字段cname = FixedCharField(max_length=25)
3. 常用的字段參數(shù)
1. null
用于表示某個(gè)字段可以為空。
2. default
該字段為默認(rèn)值
3. unique
如果設(shè)置為unique=True 則該字段在此表中必須是唯一的 。
4. db_index
如果db_index=True 則代表著為此字段設(shè)置數(shù)據(jù)庫索引。
5. DateField和DateTimeField才有的參數(shù):
auto_now_add=True --> 創(chuàng)建數(shù)據(jù)的時(shí)候自動(dòng)把當(dāng)前時(shí)間賦值
auto_add=True --> 每次更新數(shù)據(jù)的時(shí)候更新當(dāng)前時(shí)間
上述兩個(gè)不能同時(shí)設(shè)置!!!
表和表之間的關(guān)系
1. 一對(duì)多(出版社和書);1對(duì)多? ,外鍵通常設(shè)置在多的那一邊;
publisher = models.ForeignKey(to="Publisher")
數(shù)據(jù)庫中實(shí)際 生成的是一個(gè) publisher_id 字段
2. 多對(duì)多(作者和書);多對(duì)多,通常設(shè)置在正向查詢多的那一邊;比如我用author 查詢 book 比較多,則把外鍵放在author.
books = models.ManyToManyField(to="Book")
在數(shù)據(jù)庫中:
是通過第三張表建立的關(guān)系(默認(rèn)第三張表名 為字段_另一個(gè)多對(duì)多的字段)
related_name='books')
#反向操作時(shí),使用的字段名,用于代替原反向查詢時(shí)的'表名_set'。#在數(shù)據(jù)庫里面生成的字段為 publisher_id 是出版社的id#Book.object.publisher 為該書對(duì)應(yīng)的出版社的對(duì)象;def __str__(self):return "Publisher_object:{}".format(self.bookname)#出版社 class Publisher(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(null=False,max_length=15,unique=True)def __str__(self):return "Publisher_object:{}".format(self.name)# class Meta:# ordering ='id'# 書和出版社是,1對(duì)1的(ForeignKey(to=)),是需要添加外鍵的# 而書和作者是多對(duì)多的,一本書可以有多個(gè)作者,還有一個(gè)作者也可能有多本書,即多對(duì)多的時(shí)候用(ManyToManyField(to=)) #然后ROM會(huì)自動(dòng)的幫你生成另外的一張表來表示多對(duì)多的關(guān)系,這個(gè)列子生產(chǎn)的另外一個(gè)表為author_book; # 作者 class Author(models.Model):id = models.AutoField(primary_key=True)author_name = models.CharField(null=False, max_length=15)#多對(duì)多的book = models.ManyToManyField(to="Book")def __str__(self):return "Publisher_object:{}".format(self.author_name)
詳細(xì)參考(點(diǎn)我)
3. 一對(duì)一? ;比如作者和作者詳情,一個(gè)作者只能對(duì)于自己的作者詳情;
1. 什么時(shí)候用一對(duì)一?
當(dāng) 一張表的某一些字段查詢的比較頻繁,另外一些字段查詢的不是特別頻繁
把不怎么常用的字段 單獨(dú)拿出來做成一張表 然后用過一對(duì)一關(guān)聯(lián)起來
2. 優(yōu)勢
既保證數(shù)據(jù)都完整的保存下來,又能保證大部分的檢索更
3. ORM中的用法
OneToOneField(to="")
舉例:作者和作者詳情是一對(duì)一的;跟一對(duì)多,用法相同,只不過detail里面的不能重復(fù);在數(shù)據(jù)庫中也是多一個(gè)detail_id 字段
總結(jié)+練習(xí)ORM(多表的查詢)
# #####################基于對(duì)象查詢(子查詢)############################### 按字段(publish)# 一對(duì)多 book -----------------> publish# <----------------# book_set.all()# 正向查詢按字段:# 查詢python這本書籍的出版社的郵箱# python=models.Book.objects.filter(title="python").first()# print(python.publish.email)# 反向查詢按 表名小寫_set.all()# 蘋果出版社出版的書籍名稱# publish_obj=models.Publish.objects.filter(name="蘋果出版社").first()# for obj in publish_obj.book_set.all():# print(obj.title)# 按字段(authors.all())# 多對(duì)多 book -----------------------> author# <----------------# book_set.all()# 查詢python作者的年齡# python = models.Book.objects.filter(title="python").first()# for author in python.authors.all():# print(author.name ,author.age)# 查詢alex出版過的書籍名稱# alex=models.Author.objects.filter(name="alex").first()# for book in alex.book_set.all():# print(book.title)# 按字段 authorDetail# 一對(duì)一 author -----------------------> authordetail# <----------------# 按表名 author# 查詢alex的手機(jī)號(hào)# alex=models.Author.objects.filter(name='alex').first()# print(alex.authorDetail.telephone)# 查詢家在山東的作者名字# ad_list=models.AuthorDetail.objects.filter(addr="shandong")## for ad in ad_list:# print(ad.author.name)'''對(duì)應(yīng)sql:select publish_id from Book where title="python"select email from Publish where nid = 1'''# #####################基于queryset和__查詢(join查詢)############################# 正向查詢:按字段 反向查詢:表名小寫# 查詢python這本書籍的出版社的郵箱# ret=models.Book.objects.filter(title="python").values("publish__email")# print(ret.query)'''select publish.email from Book left join Publish on book.publish_id=publish.nid where book.title="python"'''# 蘋果出版社出版的書籍名稱# 方式1:# ret1 = models.Publish.objects.filter(name="蘋果出版社").values("book__title")# print("111111111====>", ret1.query)# # 方式2:# ret2 = models.Book.objects.filter(publish__name="蘋果出版社").values("title")# print("2222222222====>", ret2.query)## # 查詢alex的手機(jī)號(hào)# # 方式1:# ret = models.Author.objects.filter(name="alex").values("authorDetail__telephone")## # 方式2:# models.AuthorDetail.objects.filter(author__name="alex").values("telephone")# 查詢手機(jī)號(hào)以151開頭的作者出版過的書籍名稱以及書籍對(duì)應(yīng)的出版社名稱 ; 跨5張表; 都聯(lián)合起來;ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="151").values('title', "publish__name")print(ret)# 作者 class Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()phone = models.IntegerField()books = models.ManyToManyField(to="Book", related_name="authors")detail = models.OneToOneField(to="AuthorDetail")def __str__(self):return self.name# 作者詳情 class AuthorDetail(models.Model):# 愛好hobby = models.CharField(max_length=32)# 地址addr = models.CharField(max_length=128)
轉(zhuǎn)載于:https://www.cnblogs.com/zenghui-python/p/10800176.html
總結(jié)
以上是生活随笔為你收集整理的Django基础——ORM字段和字段参数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Angular2入门--架构概览
- 下一篇: 第十周总结