Django ORM 操做

經常使用字段及字段屬性

 

 

 

AutoField

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

IntegerField

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

CharField

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

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

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

 

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)
View Code

 

 

 

DateField

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

DateTimeField

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

 

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)',
ORM與MySQL字段對應關係

 

null

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

unique

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

db_index

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

default

爲該字段設置默認值。

 

auto_now_add

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

auto_now

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


foregnkey

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

ForeignKey能夠和其餘表作關聯關係同時也能夠和自身作關聯關係。注意:foregnkey字段不須要爲

字段名添加__id,Django會自動添加。

 

to

設置要關聯的表

to_field

設置要關聯的表的字段

on_delete

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

models.CASCADE

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

db_constraint

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

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

 

OneToOneField

一對一字段。

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

 

to

設置要關聯的表。

to_field

設置要關聯的字段。

on_delete

當刪除關聯表中的數據時,當前表與其關聯的行的行爲。(參考上面的例子)

 

在進行通常操做時先配置一下參數,使得咱們能夠直接在Django頁面中運行咱們的測試腳本

 

 

這樣就能夠直接運行你的test.py文件來運行測試

 

操做下面的操做以前,咱們實現建立好了數據表,這裏主要演示下面的操做,再也不細講建立準備過程

<1> all(): 查詢全部結果

<2> filter(**kwargs): 它包含了與所給篩選條件相匹配的對象

<3> get(**kwargs): 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。

<4> exclude(**kwargs): 它包含了與所給篩選條件不匹配的對象

<5> values(*field): 返回一個ValueQuerySet——一個特殊的QuerySet,運行後獲得的並非一系列model的實例化對象,而是一個可迭代的字典序列

<6> values_list(*field): 它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列

<7> order_by(*field): 對查詢結果排序

<8> reverse(): 對查詢結果反向排序,請注意reverse()一般只能在具備已定義順序的QuerySet上調用(在model類的Meta中指定ordering或調用order_by()方法)。

<9> distinct(): 從返回結果中剔除重複紀錄(若是你查詢跨越多個表,可能在計算QuerySet時獲得重複的結果。此時可使用distinct(),注意只有在PostgreSQL中支持按字段去重。)

<10> count(): 返回數據庫中匹配查詢(QuerySet)的對象數量。

<11> first(): 返回第一條記錄

<12> last(): 返回最後一條記錄

<13> exists(): 若是QuerySet包含數據,就返回True,不然返回False

 

 

 

Django測試準備工做

  1 建立一個專門用於測試的文件,2 複製入口文件manage.py 中的下方代碼,注意導入必須在main下方導入。

import os
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day58.settings")
    import django
    django.setup()
    from app01 import models

 

Django終端打印SQL語句

若是你想知道你對數據庫進行操做時,Django內部究竟是怎麼執行它的sql語句時能夠加下面的配置來查看

在Django項目的settings.py文件中,在最後複製粘貼以下代碼:

 
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

 

 

 

數據增刪改操做

 

 

 單表操做:

    # 新增數據
    # 基於create建立
    # user_obj = models.User.objects.create(name='tank',age=73,register_time='2019-2-14')
    # print(user_obj.register_time)
    # 基於對象的綁定方法建立
    # user_obj = models.User(name='kevin',age=30,register_time='2019-1-1')
    # user_obj.save()
    # from datetime import datetime
    # ctime = datetime.now()
    # models.User.objects.create(name='egon', age=18, register_time=ctime)
    # 修改數據
    # 基於對象
    # user_obj = models.User.objects.filter(name='jason').first()
    # user_obj.age = 17
    # user_obj.save()
    # 基於queryset
    # models.User.objects.filter(name='kevin').update(age=66)

 注意:filter()中多個鍵值對是and關係

    # 刪除數據
    # 基於queryset
    # models.User.objects.filter(name='egon').delete()
    # 基於對象
    # user_obj = models.User.objects.filter(name='owen').first()
    # user_obj.delete()

 

多表操做:

   如何確立表關係:
                一個A可否有多個B   
                一個B可否有對個A
                
                若是二者都能那麼就是                     多對多
                若是隻有一方能夠                         一對多
                若是雙方都不能夠可是二者卻有關係        一對一

   表關係:
                一對一(OneToOneField):不管建在哪一方均可以,可是推薦建在查詢頻率較高的一方
                一對多(ForeignKey):建在多的那一方
                多對多(ManyToManyField):不管建在哪一方均可以,可是推薦建在查詢頻率較高的一方

 外鍵字段的增刪改查
                    一對多字段的增刪改查(publish)
                        增
                            models.Book.objects.create(publish_id=1)
                            publish_obj = models.Publish.objects.filter(pk=1).first()
                            models.Book.objects.create(publish=publish_obj)
                           
                        改
                            book_obj = models.Book.objects.filter(pk=1).first()
                            book_obj.publish = new_publish_obj
                            
                            book_obj = models.Book.objects.filter(pk=1).update(publish_id=2)
                            book_obj = models.Book.objects.filter(pk=1).update(publish=publish_obj)
                            
                        刪
                            刪除書籍正常刪除
                            刪除出版社那麼會級聯刪除改出版社對應的全部的書籍
                            
                    多對多字段增刪改查
                        增
                            add()      
                        改
                            set()
                        刪
                            remove()
                        
                            # 上面三個方法均可以支持傳多個數字或對象,set必須接收一個可迭代對象
                        清空
                            clear()

 

數據查詢操做

 

 

  正向查詢與反向查詢的概念

     關聯字段在你當前這表查詢另外一張叫正向
                  關聯字段不在你當前這表查詢另外一張叫反向

  總結:正向查詢按字段,反向查詢按表名小寫

 

基於對象
                book_obj = models.Book.objects.filter(pk=1).first()
                book_obj.publish.addr
                book_obj.publish.name
                book_obj.authors.all()
                
                publish_obj = models.Publish.objects.filter(pk=1).first()
                publish_obj.book_set.all()
                
                
            基於雙下劃線的跨表查詢
                res = models.Book.objects.filter(publish__name='東方出版社',title='金梅').values('title','publish__name','authors__authordetail__phone')
               

 

  聚合查詢

    aggregate

    annotate(group by)

 

 queryset對象.query也可以查看內部對應的sql語句
                all()
                filter()
                values()
                value_list()
                order_by()
                reverse()
                distinct()
                exclude()
                
                
                count()      計數
                exists()     布爾值
                get()        數據對象自己
                first()
                last()

 

 聚合查詢            from django.db.models import Max,Min,Sum,Count,Avg                aggragate()                分組查詢(group by)            annotate()            group_concat()   concat()       

相關文章
相關標籤/搜索