1. 程式人生 > >ORM基礎之ORM介紹和基礎操作

ORM基礎之ORM介紹和基礎操作

複製程式碼
一、ORM介紹
1、ORM概念
物件關係對映(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向物件與關係資料庫存在的互不匹配的現象的技術。
簡單的說,ORM是通過使用描述物件和資料庫之間對映的元資料,將程式中的物件自動持久化到關係資料庫中。
ORM在業務邏輯層和資料庫層之間充當了橋樑的作用。


2、ORM由來
讓我們從O/R開始。字母O起源於"物件"(Object),而R則來自於"關係"(Relational)。
幾乎所有的軟體開發過程中都會涉及到物件和關係資料庫。在使用者層面和業務邏輯層面,我們是面向物件的。當物件的資訊發生變化的時候,我們就需要把物件的資訊儲存在關係資料庫中。
按照之前的方式來進行開發就會出現程式設計師會在自己的業務邏輯程式碼中夾雜很多SQL語句用來增加、讀取、修改、刪除相關資料,而這些程式碼通常都是重複的。


3、ORM的優勢 ORM解決的主要問題是物件和關係的對映。它通常把一個類和一個表一一對應,類的每個例項對應表中的一條記錄,類的每個屬性對應表中的每個欄位。 ORM提供了對資料庫的對映,不用直接編寫SQL程式碼,只需像操作物件一樣從資料庫操作資料。 讓軟體開發人員專注於業務邏輯的處理,提高了開發效率。 4、ORM的劣勢 ORM的缺點是會在一定程度上犧牲程式的執行效率。 ORM用多了SQL語句就不會寫了,關係資料庫相關技能退化... 5、ORM總結 ORM只是一種工具,工具確實能解決一些重複,簡單的勞動。這是不可否認的。 但我們不能指望某個工具能一勞永逸地解決所有問題,一些特殊問題還是需要特殊處理的。 但是在整個軟體開發過程中需要特殊處理的情況應該都是很少的,否則所謂的工具也就失去了它存在的意義。 二、Django中的ORM
1、Django專案使用MySQL資料庫 1. 手動新建一個數據庫 2. 在Django專案的settings.py檔案中,配置資料庫連線資訊: DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", "NAME": "你的資料庫名稱", # 需要自己手動建立資料庫 "USER": "資料庫使用者名稱", "PASSWORD": "資料庫密碼", "HOST": "資料庫IP", "POST
": 3306 } } 3. 告訴Django用什麼模組連線MySQL,在和settings.py同級的__init__.py中: import pymysql pymysql.install_as_MySQLdb() 4. 在app下面的models.py中建立類,類一定要繼承models.Model 5.執行兩個命令 1. python manage.py makemigrations --> 判斷models.py中是否有改動,把改動記錄到migrations目錄下 2. python manage.py migrate --> 把改動翻譯成SQL語句去資料庫執行 注意:當專案中不止有一個APP時,python manage.py makemigrations appname 可以單獨判斷某個app裡面的models.py的變更 2、Model 在Django中model是你資料的單一、明確的資訊來源。它包含了你儲存的資料的重要欄位和行為。通常,一個模型(model)對映到一個數據庫表 基本情況: 每個模型都是一個Python類,它是django.db.models.Model的子類。 模型的每個屬性都代表一個數據庫欄位。 綜上所述,Django為您提供了一個自動生成的資料庫訪問API。、 3、說明 ORM定義表 from django.db import models class Book(models.Model): title = models.CharField(max_length=20) publisher = models.CharField(max_length=30) title 和 publisher 是模型的欄位。每個欄位被指定為一個類屬性,每個屬性對映到一個數據庫列。 上面的模型等於下面的SQL建表語句 CREATE TABLE myapp_book ( "id" serial NOT NULL PRIMARY KEY, "title" varchar(20) NOT NULL, "publisher" varchar(30) NOT NULL ); 表myapp_book的名稱是自動生成的,如果你要自定義表名,需要在model的Meta類中指定 db_table 引數,強烈建議使用小寫表名,特別是使用MySQL作為後端資料庫時。 id欄位是自動新增的,如果你想要指定自定義主鍵,只需在其中一個欄位中指定 primary_key=True 即可。如果Django發現你已經明確地設定了Field.primary_key,它將不會新增自動ID列。 Django會根據配置檔案中指定的資料庫後端型別來生成相應的SQL語句。 Django支援MySQL5.5及更高版本。 4、欄位 總覽
    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)
        - 二進位制型別
欄位總覽
 
  

 


常用欄位
1. AutoField()  *****
     - int自增列,必須填入引數 primary_key=True
     - 當model中如果沒有自增列,則自動會建立一個列名為id的列(即自增的id主鍵)

2. IntegerField  *****
    - 整數列(有符號的) -2147483648 ~ 2147483647

3. BooleanField
    - 布林值型別

4. CharField  *****
    - 字元型別varchar
    - 必須提供max_length引數, max_length表示字元長度

5. TextField
    - 文字型別

6. EmailField
    - 字串型別,Django Admin以及ModelForm中提供驗證機制

7. GenericIPAddressField
    - 字串型別,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"

8. UUIDField  *****
    - 字串型別,Django Admin以及ModelForm中提供對UUID格式的驗證

9. FileField
    - 字串,路徑儲存在資料庫,檔案上傳到指定目錄
    - 引數:
        upload_to = ""      上傳檔案的儲存路徑
        storage = None      儲存元件,預設django.core.files.storage.FileSystemStorage

10. ImageField
    - 字串,路徑儲存在資料庫,檔案上傳到指定目錄
    - 引數:
        upload_to = ""      上傳檔案的儲存路徑
        storage = None      儲存元件,預設django.core.files.storage.FileSystemStorage
        width_field=None,   上傳圖片的高度儲存的資料庫欄位名(字串)
        height_field=None   上傳圖片的寬度儲存的資料庫欄位名(字串)

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

12. DateField    *****
    - 日期格式      YYYY-MM-DD

13. TimeField
    - 時間格式      HH:MM[:ss[.uuuuuu]]

14. FloatField
    - 浮點型

15. DecimalField   *****
    - 10進位制小數
    - 引數:
        max_digits,小數總長度
        decimal_places,小數位長度


5、自定義欄位
1.自定義char型別欄位:
from django.db import models


class MycharField(models.Field):
    """
       自定義的char型別的欄位類
    """
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        super(MycharField, self).__init__(max_length=max_length, *args, **kwargs)

    def db_type(self, connection):
        """
        限定生成資料庫表的欄位型別為char,長度為length指定的值
        """
        return 'char(%s)' % self.max_length


class UserInfo(models.Model):
    name = MycharField(max_length=12)


    
2.自定義無符號整數字段:
class UnsignedIntegerField(models.IntegerField):
    def db_type(self, connection):
        return 'integer UNSIGNED'
    
    
    
3.返回值為欄位在資料庫中的屬性,Django欄位預設的值為:
    '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)',
欄位的屬性
 
  

 

6、欄位引數
null                資料庫中欄位是否可以為空
db_column           資料庫中欄位的列名
default             資料庫中欄位的預設值
primary_key         資料庫中欄位是否為主鍵
db_index            資料庫中欄位是否可以建立索引
unique              資料庫中欄位是否可以建立唯一索引
unique_for_date     資料庫中欄位【日期】部分是否可以建立唯一索引
unique_for_month    資料庫中欄位【月】部分是否可以建立唯一索引
unique_for_year     資料庫中欄位【年】部分是否可以建立唯一索引

verbose_name        Admin中顯示的欄位名稱
blank               Admin中是否允許使用者輸入為空
editable            Admin中是否可以編輯
help_text           Admin中該欄位的提示資訊
choices             Admin中顯示選擇框的內容,用不變動的資料放在記憶體中從而避免跨表操作
                    如:sex = models.IntegerField(choices=[(1, ''), (2, ''), (3, '保密')], default=3)

error_messages      自定義錯誤資訊(字典型別),從而定製想要顯示的錯誤資訊;
                    字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                    如:{'null': "不能為空.", 'invalid': '格式錯誤'}

validators          自定義錯誤驗證(列表型別),從而定製想要的驗證規則
                    from django.core.validators import RegexValidator
                    from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
                    MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                    如:
                        test = models.CharField(
                            max_length=32,
                            error_messages={
                                'c1': '優先錯資訊1',
                                'c2': '優先錯資訊2',
                                'c3': '優先錯資訊3',
                            },
                            validators=[
                                RegexValidator(regex='root_\d+', message='錯誤了', code='c1'),
                                RegexValidator(regex='root_112233\d+', message='又錯誤了', code='c2'),
                                EmailValidator(message='又錯誤了', code='c3'), ]
                        )
欄位引數總覽
 
  

常用欄位的引數
1.null                資料庫中欄位是否可以為空
2.db_column           資料庫中欄位的列名
3.default             資料庫中欄位的預設值
4.primary_key         資料庫中欄位是否為主鍵
5.db_index            資料庫中欄位是否可以建立索引
6.unique              資料庫中欄位是否可以建立唯一索引
7.unique_for_date     資料庫中欄位【日期】部分是否可以建立唯一索引
8.unique_for_month    資料庫中欄位【月】部分是否可以建立唯一索引
9.unique_for_year     資料庫中欄位【年】部分是否可以建立唯一索引


10.DatetimeField和Datefield獨有的引數:
    auto_now_add = True        --> 當前資料的建立時間
    auto_now = True            --> 當前資料的最後修改時間
    注意:auto_now_add和auto_now 不能寫在同一個欄位上

11. 帶choice引數的欄位
    get_欄位名_display()  --> 獲取choice欄位的顯示值
    例如:
        sex = models.IntegerField(choices=[(1, ''), (2, ''), (3, '保密')], default=3)
        get_sex_display()  --> 保密

12. 建表的元資訊
class Meta:
    db_table = '表名'
    unique_together = (('ip', 'port'),)
    index_together = (("pub_date", "deadline"),)



7、元資訊
class UserInfo(models.Model):
        nid = models.AutoField(primary_key=True)
        username = models.CharField(max_length=32)
        class Meta:
            # 資料庫中生成的表名稱預設是app名稱 + 下劃線 + 類名(全小寫)
            # 可以通過db_table進行修改
            db_table = "userinfo"  # 告訴Django這個表名就叫userinfo,不要預設建成 app名稱_userinfo

            # 聯合索引
            index_together = [
                ("pub_date", "deadline"),
            ]

            # 聯合唯一索引
            unique_together = (("ip", "port"),)

            # admin中顯示的表名稱
            verbose_name

            # verbose_name加s
            verbose_name_plural

例如:
# 部落格表
class Blog(models.Model):
    title = models.CharField(max_length=32)
    push_time = models.DateTimeField(auto_now_add=True)  # 建立時間
    edit_time = models.DateTimeField(auto_now=True)  # 最後修改時間

    class Meta:
        db_table = 'blog'  # 控制建表名稱


        
        
# 應用程式表    
class Size(models.Model):
    ip = models.GenericIPAddressField()
    port = models.IntegerField()

    class Meta:
        unique_together = (('ip', 'port'),)



三、ORM的相關操作
小知識:
去manage.py把__name__的下一行,一直到最上面的那幾行程式碼複製到一個py檔案,
import django 
django.setup()
from appname.models import TableName 
測試內容
小知識點
 
  

 


UserInfo表:
class UserInfo(models.Model):
    name = MycharField(max_length=12)
    birthday = models.DateTimeField(verbose_name='生日', null=True)
    sex = models.IntegerField(choices=[(1, ''), (2, ''), (3, '保密')], default=3)

    def __str__(self):
        return self.name
UserInfo
 
  

 

1、基本操作13條(必會)
1-1、返回QuerySet物件(列表)的方法(返回的是列表,列表中的元素是物件)
all()
    查詢所有結果
    
filter(**kwargs)
    它包含了與所給篩選條件相匹配的物件

exclude(**kwargs)
    它包含了與所給篩選條件不匹配的物件

order_by(*field)
    對查詢結果排序

reverse()
    對查詢結果反向排序,請注意reverse()通常只能在具有已定義順序的QuerySet上呼叫(在model類的Meta中指定ordering或呼叫order_by()方法)。

distinct()
     從返回結果中剔除重複紀錄(如果你查詢跨越多個表,可能在計算QuerySet時得到重複的結果。此時可以使用distinct(),注意只有在PostgreSQL中支援按欄位去重。)


1-2、特殊的QuerySet(返回的是列表,但列表中的元素不是物件)
values(*field)
    返回一個ValueQuerySet——一個特殊的QuerySet,執行後得到的並不是一系列model的例項化物件,而是一個可迭代的字典序列
   User.objects.all().values('id', 'name')
   QuerySet [{'id': 1, 'name': '小明'}, {'id': 2, 'name': '小東'}] values_list(
*field) 它與values()非常相似,它返回的是一個元組序列,values返回的是一個字典序列
   User.objects.all().values_list('id')
   QuerySet [(1, '小明'), (2, '小東')]
1-3、返回具體物件的 get(**kwargs) 返回與所給篩選條件相匹配的物件,返回結果有且只有一個,如果符合篩選條件的物件超過一個或者沒有都會丟擲錯誤。 first() 返回第一條記錄 last() 返回最後一條記錄 1-4、返回布林值的方法 exists() 如果QuerySet包含資料,判斷表中是否有資料,有就返回True,否則返回False 1-5、返回數字的方法 count() 返回資料庫中匹配查詢(QuerySet)的物件數量。 例子: # all()找到UserInfo表中所有的物件 ret = UserInfo.objects.all() print(ret) # filter()找到名字是小明的那個人 ret1 = UserInfo.objects.filter(name='小明') print(ret1) # exclude()找到名字不是小明的那些人 ret1 = UserInfo.objects.exclude(name='小明') print(ret1) # values()返回的還是列表,但列表中的不是物件,而是字典 ret = UserInfo.objects.all().values('name', 'sex') print(ret) # values_list()返回的還是列表,但列表中的不是物件,而是元組 ret1 = UserInfo.objects.all().values_list('name', 'sex') print(ret1) # order_by('xx')根據xx升序排序,order_by('-xx')根據xx降序排序 ret = UserInfo.objects.all().order_by('id') ret1 = UserInfo.objects.all().order_by('-id') ret2 = UserInfo.objects.all().order_by('birthday') print(ret) print(ret1) print(ret2) # reverse() 對排序的結果進行反序 ret = UserInfo.objects.all().order_by('id').reverse() print(ret) # count()返回數量 ret = UserInfo.objects.all().count() print(ret) # first()返回第一條記錄和last()返回最後一條記錄 ret1 = UserInfo.objects.all().first() ret2 = UserInfo.objects.all().last() print(ret1) print(ret2) # exists()判斷表中是否有資料 ret = UserInfo.objects.exists() print(ret) 2、單表查詢之神奇的雙下劃線 # __lt:查詢id值小於3的物件 ret = UserInfo.objects.filter(id__lt=3) print(ret) # __lte:查詢id值小於等於3的物件 ret = UserInfo.objects.filter(id__lte=3) print(ret) # __gt:查詢id值大於3的物件 ret = UserInfo.objects.filter(id__gt=3) print(ret) # __in:id是1,3,5的物件 ret = UserInfo.objects.filter(id__in=[1, 3, 5]) print(ret) # __in:id不是1,3,5的物件 ret = UserInfo.objects.exclude(id__in=[1, 3, 5]) print(ret) # __contains:找到名字包含"小"的物件,__icontains:和__contains一樣,但是不區分大小寫 ret = UserInfo.objects.filter(name__contains='') print(ret) # __range:找到範圍在[1, 3]之間的物件 ret = UserInfo.objects.filter(id__range=[1, 3]) print(ret) # __endswith:找到以"仔"結尾的物件 ret = UserInfo.objects.filter(name__endswith='') print(ret) # date欄位還可以使用__year、__month等:找到10月出生的人 ret = UserInfo.objects.filter(birthday__month=10) print(ret)

# __isnull:判斷這個欄位是否為空
ret = UserInfo.objects.filter(name__isnull=True)
print(ret)
# 雙下還可以鏈式操作:找到出生小於2000年的 ret = UserInfo.objects.filter(birthday__year__lt=2000) print(ret)
複製程式碼

 

複製程式碼
一、ORM介紹
1、ORM概念
物件關係對映(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向物件與關係資料庫存在的互不匹配的現象的技術。
簡單的說,ORM是通過使用描述物件和資料庫之間對映的元資料,將程式中的物件自動持久化到關係資料庫中。
ORM在業務邏輯層和資料庫層之間充當了橋樑的作用。


2、ORM由來
讓我們從O/R開始。字母O起源於"物件"(Object),而R則來自於"關係"(Relational)。
幾乎所有的軟體開發過程中都會涉及到物件和關係資料庫。在使用者層面和業務邏輯層面,我們是面向物件的。當物件的資訊發生變化的時候,我們就需要把物件的資訊儲存在關係資料庫中。
按照之前的方式來進行開發就會出現程式設計師會在自己的業務邏輯程式碼中夾雜很多SQL語句用來增加、讀取、修改、刪除相關資料,而這些程式碼通常都是重複的。


3、ORM的優勢
ORM解決的主要問題是物件和關係的對映。它通常把一個類和一個表一一對應,類的每個例項對應表中的一條記錄,類的每個屬性對應表中的每個欄位。 
ORM提供了對資料庫的對映,不用直接編寫SQL程式碼,只需像操作物件一樣從資料庫操作資料。
讓軟體開發人員專注於業務邏輯的處理,提高了開發效率。


4、ORM的劣勢
ORM的缺點是會在一定程度上犧牲程式的執行效率。
ORM用多了SQL語句就不會寫了,關係資料庫相關技能退化...


5、ORM總結
ORM只是一種工具,工具確實能解決一些重複,簡單的勞動。這是不可否認的。
但我們不能指望某個工具能一勞永逸地解決所有問題,一些特殊問題還是需要特殊處理的。
但是在整個軟體開發過程中需要特殊處理的情況應該都是很少的,否則所謂的工具也就失去了它存在的意義。



二、Django中的ORM
1、Django專案使用MySQL資料庫
1. 手動新建一個數據庫

2. 在Django專案的settings.py檔案中,配置資料庫連線資訊:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "你的資料庫名稱",  # 需要自己手動建立資料庫
        "USER": "資料庫使用者名稱",
        "PASSWORD": "資料庫密碼",
        "HOST": "資料庫IP",
        "POST": 3306
    }
}

3. 告訴Django用什麼模組連線MySQL,在和settings.py同級的__init__.py中:
import pymysql
pymysql.install_as_MySQLdb()

4. 在app下面的models.py中建立類,類一定要繼承models.Model

5.執行兩個命令
    1. python manage.py makemigrations      --> 判斷models.py中是否有改動,把改動記錄到migrations目錄下
    2. python manage.py migrate             --> 把改動翻譯成SQL語句去資料庫執行
注意:當專案中不止有一個APP時,python manage.py makemigrations appname 可以單獨判斷某個app裡面的models.py的變更


2、Model
在Django中model是你資料的單一、明確的資訊來源。它包含了你儲存的資料的重要欄位和行為。通常,一個模型(model)對映到一個數據庫表

基本情況:

每個模型都是一個Python類,它是django.db.models.Model的子類。
模型的每個屬性都代表一個數據庫欄位。
綜上所述,Django為您提供了一個自動生成的資料庫訪問API。、



3、說明
ORM定義表
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=20)
    publisher = models.CharField(max_length=30)
title 和 publisher 是模型的欄位。每個欄位被指定為一個類屬性,每個屬性對映到一個數據庫列。


上面的模型等於下面的SQL建表語句

CREATE TABLE myapp_book (
    "id" serial NOT NULL PRIMARY KEY,
    "title" varchar(20) NOT NULL,
    "publisher" varchar(30) NOT NULL
);

表myapp_book的名稱是自動生成的,如果你要自定義表名,需要在model的Meta類中指定 db_table 引數,強烈建議使用小寫表名,特別是使用MySQL作為後端資料庫時。
id欄位是自動新增的,如果你想要指定自定義主鍵,只需在其中一個欄位中指定 primary_key=True 即可。如果Django發現你已經明確地設定了Field.primary_key,它將不會新增自動ID列。
Django會根據配置檔案中指定的資料庫後端型別來生成相應的SQL語句。
Django支援MySQL5.5及更高版本。



4、欄位
總覽
    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)
        - 二進位制型別
欄位總覽
 
 

 


常用欄位
1. AutoField()  *****
     - int自增列,必須填入引數 primary_key=True
     - 當model中如果沒有自增列,則自動會建立一個列名為id的列(即自增的id主鍵)

2. IntegerField  *****
    - 整數列(有符號的) -2147483648 ~ 2147483647

3. BooleanField
    - 布林值型別

4. CharField  *****
    - 字元型別varchar
    - 必須提供max_length引數, max_length表示字元長度

5. TextField
    - 文字型別

6. EmailField
    - 字串型別,Django Admin以及ModelForm中提供驗證機制

7. GenericIPAddressField
    - 字串型別,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"

8. UUIDField  *****
    - 字串型別,Django Admin以及ModelForm中提供對UUID格式的驗證

9. FileField
    - 字串,路徑儲存在資料庫,檔案上傳到指定目錄
    - 引數:
        upload_to = ""      上傳檔案的儲存路徑
        storage = None      儲存元件,預設django.core.files.storage.FileSystemStorage

10. ImageField
    - 字串,路徑儲存在資料庫,檔案上傳到指定目錄
    - 引數:
        upload_to = ""      上傳檔案的儲存路徑
        storage = None      儲存元件,預設django.core.files.storage.FileSystemStorage
        width_field=None,   上傳圖片的高度儲存的資料庫欄位名(字串)
        height_field=None   上傳圖片的寬度儲存的資料庫欄位名(字串)

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

12. DateField    *****
    - 日期格式      YYYY-MM-DD

13. TimeField
    - 時間格式      HH:MM[:ss[.uuuuuu]]

14. FloatField
    - 浮點型

15. DecimalField   *****
    - 10進位制小數
    - 引數:
        max_digits,小數總長度
        decimal_places,小數位長度


5、自定義欄位
1.自定義char型別欄位:
from django.db import models


class MycharField(models.Field):
    """
       自定義的char型別的欄位類
    """
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        super(MycharField, self).__init__(max_length=max_length, *args, **kwargs)

    def db_type(self, connection):
        """
        限定生成資料庫表的欄位型別為char,長度為length指定的值
        """
        return 'char(%s)' % self.max_length


class UserInfo(models.Model):
    name = MycharField(max_length=12)


    
2.自定義無符號整數字段:
class UnsignedIntegerField(models.IntegerField):
    def db_type(self, connection):
        return 'integer UNSIGNED'
    
    
    
3.返回值為欄位在資料庫中的屬性,Django欄位預設的值為:
    '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)',
欄位的屬性
 
 

 

6、欄位引數
null                資料庫中欄位是否可以為空
db_column           資料庫中欄位的列名
default             資料庫中欄位的預設值
primary_key         資料庫中欄位是否為主鍵
db_index            資料庫中欄位是否可以建立索引
unique              資料庫中欄位是否可以建立唯一索引
unique_for_date     資料庫中欄位【日期】部分是否可以建立唯一索引
unique_for_month    資料庫中欄位【月】部分是否可以建立唯一索引
unique_for_year     資料庫中欄位【年】部分是否可以建立唯一索引

verbose_name        Admin中顯示的欄位名稱
blank               Admin中是否允許使用者輸入為空
editable            Admin中是否可以編輯
help_text           Admin中該欄位的提示資訊
choices             Admin中顯示選擇框的內容,用不變動的資料放在記憶體中從而避免跨表操作
                    如:sex = models.IntegerField(choices=[(1, ''), (2, ''), (3, '保密')], default=3)

error_messages      自定義錯誤資訊(字典型別),從而定製想要顯示的錯誤資訊;
                    字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                    如:{'null': "不能為空.", 'invalid': '格式錯誤'}

validators          自定義錯誤驗證(列表型別),從而定製想要的驗證規則
                    from django.core.validators import RegexValidator
                    from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
                    MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                    如:
                        test = models.CharField(
                            max_length=32,
                            error_messages={
                                'c1': '優先錯資訊1',
                                'c2': '優先錯資訊2',
                                'c3': '優先錯資訊3',
                            },
                            validators=[
                                RegexValidator(regex='root_\d+', message='錯誤了', code='c1'),
                                RegexValidator(regex='root_112233\d+', message='又錯誤了', code='c2'),
                                EmailValidator(message='又錯誤了', code='c3'), ]
                        )
欄位引數總覽
 
 

常用欄位的引數
1.null                資料庫中欄位是否可以為空
2.db_column           資料庫中欄位的列名
3.default             資料庫中欄位的預設值
4.primary_key         資料庫中欄位是否為主鍵
5.db_index            資料庫中欄位是否可以建立索引
6.unique              資料庫中欄位是否可以建立唯一索引
7.unique_for_date     資料庫中欄位【日期】部分是否可