Django之models屬性字段、關係字段、數據庫查詢優化、開啓事務、MTV、MVC模型

[TOC]python

Meta類屬性

class User(AbstractUser):
    mobile = models.CharField(max_length=11, unique=True, verbose_name='移動電話')
    icon = models.ImageField(upload_to='icon', default='icon/default.png', verbose_name='頭像')

    class Meta:
        db_table = 'o_user'  # 自定義表名
        verbose_name_plural = '用戶表'  # admin後臺管理顯示的表名
        
   def __str__(self):
    	return self.self.name  	# admin後臺顯示的單個對象名

1、經常使用字段

1.AutoField

int自增列,必須填入參數 primary_key=True。當model中若是沒有自增列,則自動會建立一個列名爲id的列。git

2.IntegerField

一個整數類型,範圍在 -2147483648 to 2147483647。(通常不用它來存手機號(位數也不夠),直接用字符串存,)面試

3.CharField

字符類型,必須提供max_length參數, max_length表示字符長度。sql

這裏須要知道的是Django中的CharField對應的MySQL數據庫中的varchar類型,沒有設置對應char類型的字段,可是Django容許咱們自定義新的字段,下面我來自定義對應於數據庫的char類型數據庫

img

自定義字段在實際項目應用中可能會常常用到,這裏須要對他留個印象!django

4.自定義及使用char

from django.db import models

# Create your models here.
#Django中沒有對應的char類型字段,可是咱們能夠本身建立
class FixCharField(models.Field):
    '''
    自定義的char類型的字段類
    '''
    def __init__(self,max_length,*args,**kwargs):
        self.max_length=max_length
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self, connection):
        '''
        限定生成的數據庫表字段類型char,長度爲max_length指定的值
        :param connection:
        :return:
        '''
        return 'char(%s)'%self.max_length
#應用上面自定義的char類型
class Class(models.Model):
    id=models.AutoField(primary_key=True)
    title=models.CharField(max_length=32)
    class_name=FixCharField(max_length=16)
    gender_choice=((1,'男'),(2,'女'),(3,'保密'))
    gender=models.SmallIntegerField(choices=gender_choice,default=3)

5.DateField

日期字段,日期格式 YYYY-MM-DD,至關於Python中的datetime.date()實例。安全

6.DateTimeField

日期時間字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],至關於Python中的datetime.datetime()實例。框架

2、字段合集

AutoField(Field)
        - int自增列,必須填入參數 primary_key=True

    BigAutoField(AutoField)
        - bigint自增列,必須填入參數 primary_key=True

        注:當model中若是沒有自增列,則自動會建立一個列名爲id的列
        from django.db import models

        class 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 ~ 32767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整數 0 ~ 32767
    IntegerField(Field)
        - 整數列(有符號的) -2147483648 ~ 2147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整數 0 ~ 2147483647

    BigIntegerField(IntegerField):
        - 長整型(有符號的) -9223372036854775808 ~ 9223372036854775807

    BooleanField(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中提供驗證 URL

    SlugField(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.FileSystemStorage

    ImageField(FileField)
        - 字符串,路徑保存在數據庫,文件上傳到指定目錄
        - 參數:
            upload_to = ""      上傳文件的保存路徑
            storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage
            width_field=None,   上傳圖片的高度保存的數據庫字段名(字符串)
            height_field=None   上傳圖片的寬度保存的數據庫字段名(字符串)

    DateTimeField(DateField)
        - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD

    TimeField(DateTimeCheckMixin, Field)
        - 時間格式      HH:MM[:ss[.uuuuuu]]

    DurationField(Field)
        - 長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值爲datetime.timedelta類型

    FloatField(Field)
        - 浮點型

    DecimalField(Field)
        - 10進制小數
        - 參數:
            max_digits,小數總長度
            decimal_places,小數位長度

    BinaryField(Field)
        - 二進制類型
對應關係:
    'AutoField': 'integer AUTO_INCREMENT',
    'BigAutoField': 'bigint AUTO_INCREMENT',
    'BinaryField': 'longblob',
    'BooleanField': 'bool',
    'CharField': 'varchar(%(max_length)s)',
    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
    'DateField': 'date',
    'DateTimeField': 'datetime',
    'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
    'DurationField': 'bigint',
    'FileField': 'varchar(%(max_length)s)',
    'FilePathField': 'varchar(%(max_length)s)',
    'FloatField': 'double precision',
    'IntegerField': 'integer',
    'BigIntegerField': 'bigint',
    'IPAddressField': 'char(15)',
    'GenericIPAddressField': 'char(39)',
    'NullBooleanField': 'bool',
    'OneToOneField': 'integer',
    'PositiveIntegerField': 'integer UNSIGNED',
    'PositiveSmallIntegerField': 'smallint UNSIGNED',
    'SlugField': 'varchar(%(max_length)s)',
    'SmallIntegerField': 'smallint',
    'TextField': 'longtext',
    'TimeField': 'time',
    'UUIDField': 'char(32)',

3、字段參數

1.null

用於表示某個字段能夠爲空。fetch

2.unique

若是設置爲unique=True 則該字段在此表中必須是惟一的 。優化

3.db_index

若是db_index=True 則表明着爲此字段設置索引。

4.default

爲該字段設置默認值。

4、DateField和DateTimeField

1.auto_now_add

配置auto_now_add=True,建立數據記錄的時候會把當前時間添加到數據庫。

publish_time = models.DateField(auto_now_add=True)
publish_time = models.DateTimeField(auto_now_add=True)

2.auto_now

配置上auto_now=True,每次更新數據記錄的時候會更新該字段。

publish_time = models.DateField(auto_now=True)
publish_time = models.DateTimeField(auto_now=True)

5、關係字段

1.ForeignKey 一對多

外鍵類型在ORM中用來表示外鍵關聯關係,通常把ForeignKey字段設置在 '一對多'中'多'的一方。

ForeignKey能夠和其餘表作關聯關係同時也能夠和自身作關聯關係。

# 圖書表
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish_time = models.DateField(auto_now_add=True)

    # 出版社外鍵
    # 一本書有一個出版社,一個出版社能夠出版多本書。一對多的關係
    publish = models.ForeignKey(to='Publish')  # 一對多
    # 一本書 能夠又多個做者,一個做者能夠寫多本書。多對多
    authors = models.ManyToManyField(to='Author')

字段參數

1.to

設置要關聯的表

2.to_field

設置要關聯的表的字段

3.on_delete

當刪除關聯表中的數據時,當前表與其關聯的行的行爲。

models.CASCADE

刪除關聯數據,與之關聯也刪除

4.db_constraint

是否在數據庫中建立外鍵約束,默認爲True。

5.其他字段參數

models.DO_NOTHING
刪除關聯數據,引起錯誤IntegrityError


models.PROTECT
刪除關聯數據,引起錯誤ProtectedError


models.SET_NULL
刪除關聯數據,與之關聯的值設置爲null(前提FK字段須要設置爲可空)


models.SET_DEFAULT
刪除關聯數據,與之關聯的值設置爲默認值(前提FK字段須要設置默認值)


models.SET

刪除關聯數據,
a. 與之關聯的值設置爲指定值,設置:models.SET(值)
b. 與之關聯的值設置爲可執行對象的返回值,設置:models.SET(可執行對象)
def func():
    return 10

class MyModel(models.Model):
    user = models.ForeignKey(
        to="User",
        to_field="id",
        on_delete=models.SET(func)
    )

2.OneToOneField 一對一

一般一對一字段用來擴展已有字段。(通俗的說就是一我的的全部信息不是放在一張表裏面的,簡單的信息一張表,隱私的信息另外一張表,之間經過一對一外鍵關聯)

# 做者表
class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    # 一個做者有一個做者詳情,一個詳情只有一個做者。一對一
    author_detail = models.OneToOneField('AuthorDetail')

字段參數

1.to

設置要關聯的表。

2.to_field

設置要關聯的字段。

3.on_delete

當刪除關聯表中的數據時,當前表與其關聯的行的行爲。

3.ManyToManyField 多對多三種建立方式

①全自動(常見)

好處:第三張表自動建立,而且會自動幫你在字段名後加'_id'後綴
不足之處:第三張表沒法擴展額外的字段,擴展性低
# 圖書表
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish_time = models.DateField(auto_now_add=True)

    # 出版社外鍵
    # 一本書有一個出版社,一個出版社能夠出版多本書。一對多的關係
    publish = models.ForeignKey(to='Publish')  # 一對多
    # 一本書 能夠又多個做者,一個做者能夠寫多本書。多對多
    authors = models.ManyToManyField(to='Author')  # Author是多對多的另外一張表名

②純手動(瞭解)

好處:第三表能夠擴展額外的字段
不足之處:orm查詢的時候會帶來不便
class Book(models.Model):
    title = models.CharField(max_length=32)

class Author(models.Model):
    name = models.CharField(max_length=32)

class Book2Author(models.Model):
    book = models.ForeignKey(to='Book')
    author = models.ForeignKey(to='Author')
    create_time = models.DateField(auto_now_add=True)

③半自動(推薦)

好處:第三張表能夠擴展任意的額外字段 還能夠利用orm 正反向查詢
不足之處:沒法利用 add  set  remove  clear 對外鍵關係表操做
可是:雖然沒法使用了 但咱們還能夠本身直接操做第三表,擴展性極高
class Book(models.Model):
	title = models.CharField(max_length=32)
	authors = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
		
class Author(models.Model):
	name = models.CharField(max_length=32)
	books = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('author','book'))
	
class Book2Author(models.Model):
	book = models.ForeignKey(to='Book')
	author = models.ForeignKey(to='Author')
	create_time = models.DateField(auto_now_add=True)   # 自動添加建立時間

6、choices參數

條件能夠被徹底列舉出來 有對應關係

該字段存的仍是數字而且沒有範圍限制,可是一旦你存的數字在你上面定義的對應關係內
    那麼你就能夠經過下面的方法獲取到數字對應的解釋信息
    get_xxx_display()  若是沒有對應關係返回的仍是數字
獲取值:user_obj.get_gender_display()
	# 只要有對應關係便可 前面不必定非要是數字
    # 若是數字沒有對應的關係,那麼仍是獲取到數字自己

1.用戶表舉例

用戶的性別
學歷
婚否
在職狀態
客戶來源
當你的數據可以被你列舉徹底  你就能夠考慮使用choices參數

2.基本運用

案例1:

# choices字段
class Userinfo(models.Model):
    username = models.CharField(max_length=32)
    gender_choices = (
        (1,'男'),
        (2,'女'),
        (3,'其餘'),
    )
    gender = models.IntegerField(choices=gender_choices)
    # 該字段仍是存數字 而且能夠匹配關係以外的數字

案例2:

record_choices = (('checked', "已簽到"),
                  ('vacate', "請假"),
                  ('late', "遲到"),
                  ('noshow', "缺勤"),
                  ('leave_early', "早退"),
                 )
record = models.CharField("上課紀錄", choices=record_choices, default="checked", max_length=64)

獲取值:

user_obj = models.Userinfo.objects.get(pk=1)  
print(user_obj.username)
print(user_obj.gender)
# 針對choices參數字段 取值的時候   get_xxx_display()
print(user_obj.get_gender_display())


# # 針對沒有註釋信息的數據  get_xxx_display()獲取到的仍是數字自己
user_obj = models.Userinfo.objects.get(pk=4)
print(user_obj.gender)
print(user_obj.get_gender_display())

7、數據庫查詢優化(面試)

1.惰性查詢

惰性:不會白白的幫你多幹事情,減緩數據庫的壓力

惰性查詢:若是下面的代碼沒有使用res,那麼就不會幫你查詢。只有使用了纔會幫你查詢。

django orm查詢都是惰性查詢
res = models.Book.objects.all()  # django orm查詢都是惰性查詢
printf(res)  # 使用了res

2.only與defer的用法

noly的使用:

res = models.Book.objects.only('title')  # 這些對象內部只有title屬性
# print(res)
for r in res:
    print(r.title)  # only括號內有title屬性,不走數據庫
    print(r.price)	# 括號內沒有price屬性,走數據庫拿

defer的使用:

res = models.Book.objects.defer('title')  # defer與only互爲反關係
print(res)

大白話總結:

大白話總結:
    defer與only互爲相反,獲取沒有的數據走數據庫拿。
    only: 括號內有指定的字段屬性
    defer:括號內沒有指定的字段屬性

3.selected_related與prefetch_related

selected_related:內部是連表操做,封裝到對象,走一次數據庫所有查出
	優勢:只走一次sql查詢
	缺點:耗時耗在 鏈接表的操做  10s

prefetch_related:內部是子查詢
	優勢:耗時耗在 查詢次數好比10次      1s
	缺點:走兩次sql查詢

使用方法:

res = models.Book.objects.select_related('publish')
print(res)

res = models.Book.objects.prefetch_related('publish')
print(res)

8、Djangi ORM 中如何開啓事物

原子性:

原子性(Atomicity),原子意爲最小的粒子,即不能再分的事務,要麼所有執行,要麼所有取消(就像上面的銀行例子)
一致性:

一致性(Consistency):指事務發生前和發生後,數據的總額依然匹配
隔離性:

隔離性(Isolation):簡單點說,某個事務的操做對其餘事務不可見的
持久性:

 持久性(Durability):當事務完成後,其影響應該保留下來,不能撤消,只能經過「補償性事務」來抵消以前的錯誤

開啓事務:

start transaction   開啓
 rollback			回滾
 commit				確認
from django.db import transaction
# django orm開啓事務操做
from django.db import transaction
with transaction.atomic():
    # 在with代碼塊中執行的orm語句同屬於一個事務
    pass

9、MTV與MVC模型

MTV: django號稱是MTV框架

M  指:models		模型
T   :templates   模版
V   :views		視圖

MVC

M:models	模型
V:views		視圖
C:contronnar  控制器(路由分發 urls.py)

本質

本質:MTV本質也是MVC

BMS

Web領域沒有絕對的安全 也沒有絕對的不安全
相關文章
相關標籤/搜索