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