Django 模型

模型基礎

模型是關於數據的惟一的、肯定的信息源。它包含您正在存儲的數據的基本字段和行爲。一般,每一個模型映射到一個數據庫表。python

基礎:git

  1. 模型是一個繼承django.db.models.Model的class類
  2. 每一個屬性對應一個數據庫字段
  3. django提供了一個自動生成的數據庫訪問API

例子:算法

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

生成數據庫文件sql

CREATE TABLE myapp_person (
    "id" serial NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);

注:table名是django自動添加的(可自定義) id是django自動添加的(可自定義) SQL語句是django自動生成的,可針對不一樣的數據庫進行遷移數據庫

當遷移models時,須要在INSTALLED_APPS中註冊當前appdjango

遷移指令:app

python manage.py makemigrations myAPP
python manage.py sqlmigrate myAPP
python manage.py migrate

Filed

模型最重要的部分就是字段,避免字段名字與models API名相同框架

Filed Types

每一個字段都必須是Field類的實例,Django使用filed類來描述一些信息:函數

  1. column type 告訴數據庫數據的類型(int,varchar,text...)
  2. widget 自動生成的form表單類型(<input type="text">)
  3. 由Django管理和自動生成表單的驗證需求

內置Filed Types

AutoField 主鍵,不指定主鍵django將自動添加一個名爲id的主鍵。

BigAutoField 主鍵 biginteger

BinaryField 二進制類型
    默認狀況下,BinaryField的editable屬性爲False,不容許包含在ModelForm中
    慎用,此字段不能代替真正的文件處理

BooleanField 布爾類型
    widget默認爲CheckboxInput,若是null=True則爲NullBolleanSelect
    若是Field.default沒有指定,BooleanField默認值爲None

CharField string類型
    若是數據量很大,使用TextFiled
    widget默認爲TextInput

DateField datetime.date類型
    auto_now屬性,設置爲True時執行model.save自動更新此字段爲當前時間,且修改此字段值將無效
    auto_now_add屬性,設置爲True時執行model.add自動添加此字段爲當前時間,且修改此字段值將無效
    若是你只想修改這個字段,使用defalut=tdate.today,它將datetime.date.today()賦值給此字段,且支持修改。對於DateTimeField類型,使用default=timezone.noe,它將django.utils.timezone.now()賦值給此字段。
    auto_now_add, auto_now, default是獨有的,不能混合使用
    auto_now or auto_now_add to True將致使 editable=False and blank=True 
    auto_now和auto_now_add選項在建立或更新時老是使用默認時區中的日期

DateTimeField datetime.datetime類型
    與DateField相似

DecimalField Decimal類型
    max_digits屬性 最大位數
    decimal_places屬性 小數位數
    最大位數-小數位數=最大整數位數

DurationField 時間間隔字段
    在大多數狀況下,使用DurationField算法是可行的。然而,在除PostgreSQL以外的全部數據庫上,將DurationField的值與DateTimeField實例上的算術值進行比較將沒法正常工做

EmailField email類型

FileField 文件上傳類型
    upload_to屬性 設置文件上傳的路徑
        upload = models.FileField(upload_to='uploads/')
        upload = models.FileField(upload_to='uploads/%Y/%m/%d/')
    使用 FileField,須要對settings.py作以下配置
        # 與用戶上傳相關的配置
        MEDIA_URL="/media/"  # 訪問路徑
        MEDIA_ROOT=os.path.join(BASE_DIR,"media")  # 保存路徑

    upload_to也能夠是一個方法
        def user_directory_path(instance, filename):
            # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
            return 'user_{0}/{1}'.format(instance.user.id, filename)
        
        class MyModel(models.Model):
            upload = models.FileField(upload_to=user_directory_path)

    當訪問FileField時,會獲得一個FieldFile實例,做爲訪問底層文件的代理。

FilePathField 文件路徑類型
    當你只想保存已存在的文件路徑而不是獲取用戶上傳的文件時使用此字段,不使用FileField

    class FilePathField(path=None, match=None, recursive=False, max_length=100, **options)
    一個CharField,其選擇僅限於文件系統上某個目錄中的文件名。有三個特殊的參數,第一個是必須的

    path:文件路徑,最好配置在settings.py中
    match:文件名正則匹配表達式
    recursive:指定是否應包括路徑的全部子目錄
    allow_files:指定是否應包括指定位置中的文件 必須是True
    allow_folders:指定是否包含指定位置的文件夾 必須是True

FloatField 浮點類型
    將被解析成python Float類型

ImageField 圖片類型
    繼承了FileField類,將驗證是否爲圖片
    height_field屬性:文件save時將被保存成此字段高
    width_field屬性:文件save時將被保存成此字段寬

IntegerField 整數類型
    保存int類型

GenericIPAddressField IP類型
    IPv4 or IPv6地址,默認widget是TextInput
    protocol屬性:value in('both'(default) 'IPv4' 'IPv6')
    unpack_ipv4屬性:解包IPv4映射地址,好比::ffff:192.0.2.1。若是啓用此選項,該地址將解壓縮到192.0.2.1。默認是禁用的。只能在協議設置爲'both'時使用。

NullBooleanField 布爾類型
    與 BooleanField with null=True效果同樣

PositiveIntegerField 正整數類型
    與 IntegerField相似,只能保存正整數

PositiveSmallIntegerField 正整數類型
    與 PositiveIntegerField相似,範圍:0 to 32767

SlugField 限定string類型
    slug是對某物的縮寫,僅包含字母、數字、下劃線或連字符。它們一般用於url中。
    allow_unicode:設置爲True時,除了ASCII還可使用unicode字符,默認爲False

SmallIntegerField 整數類型
    與 IntegerField相似,範圍:-32768 to 32767

TextField 文本類型
    large text filed

TimeField 時間類型
    datetime.time

URLField
    A CharField for a URL, validated by URLValidator
    The default form widget for this field is a TextInput.

UUIDField UUID類型

    import uuid
    from django.db import models
    
    class MyUUIDModel(models.Model):
        id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
        # other fields

Relationship fields
    Django還定義了一組表示關係的字段

ForeignKey 外鍵類型
    在多對一關係使用它

    from django.db import models
    
    class Car(models.Model):
        manufacturer = models.ForeignKey(
            'Manufacturer',
            on_delete=models.CASCADE,
        )
        # ...
    
    class Manufacturer(models.Model):
        # ...
        pass

    #ForeignKey與抽象類
    from django.db import models
    
    class AbstractCar(models.Model):
        manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
    
        class Meta:
            abstract = True

    from django.db import models
    from products.models import AbstractCar
    
    class Manufacturer(models.Model):
        pass
    
    class Car(AbstractCar):
        pass

    on_delete屬性:指向的表數據刪除時若是操做此字段
    limit_choices_to屬性:限制指向表數據的字段值
        staff_member = models.ForeignKey(
            User,
            on_delete=models.CASCADE,
            limit_choices_to={'is_staff': True},  # 只有User表中的is_staff屬性爲True的才能夠賦值給此字段
        )

        # limit_choices_to能夠指定給一個函數
        def limit_pub_date_choices():
            return {'pub_date__lte': datetime.date.utcnow()}
        
        limit_choices_to = limit_pub_date_choices

    related_name屬性:從相關對象返回到此對象的關係使用的名稱。請參閱相關對象文檔。注意,在定義抽象模型上的關係時,必須設置此值;當你這樣作的時候,一些特殊的語法是可用的。
                     若是您但願Django不要建立反向關係,能夠將related_name設置爲'+'或以'+'結束它。默認爲 表名_set

    related_query_name屬性:用於目標模型中反向篩選器名稱的名稱。
        # Declare the ForeignKey with related_query_name
        class Tag(models.Model):
            article = models.ForeignKey(
                Article,
                on_delete=models.CASCADE,
                related_name="tags",
                related_query_name="tag",
            )
            name = models.CharField(max_length=255)
        
        # That's now the name of the reverse filter
        article_obj = Article.objects.filter(tag__name="important")
        article_obj.tags.all()

    to屬性:關係所在的對象

    to_field屬性:關係所在的相關對象上的字段。默認狀況下,Django使用相關對象的主鍵。若是引用不一樣的字段,則該字段必須具備唯一=True。
    
    db_constraint屬性:控制是否應該在數據庫中爲該外鍵建立約束。默認爲真,這幾乎確定是你想要的;將此設置爲False可能對數據完整性很是不利。

    swappable屬性:若是這個ForeignKey指向一個可切換的模型,則控制遷移框架的反應。若是它是True(默認值),那麼若是ForeignKey指向的模型與設置的當前值匹配。AUTH_USER_MODEL(或另外一個可切換模型設置)關係將使用對該設置的引用而不是直接對模型的引用存儲在遷移中。
    若是您確信您的模型應該始終指向被簽入的模型——例如,若是它是專門爲您的自定義用戶模型設計的配置文件模型,那麼您只但願將其重寫爲False。
    將它設置爲False並不意味着你能夠引用一個可切換模型即便是換出——假只是意味着遷移用此ForeignKey老是參考的模型指定(這將會失敗若是用戶試圖運行一個用戶模型你不支持,例如)。
    若是有疑問,讓它默認爲True


ManyToManyField
    多對多關係

    limit_choices_to在ManyToManyField上使用使用through參數指定的自定義中間表時沒有任何效果
    
    through屬性:Django將自動生成一個表來管理多對多關係。可是,若是要手動指定中間表,可使用through選項指定Django模型,該模型表示要使用的中間表。
    through_fields屬性:指定through的表後,須要聲明表中關聯的字段
        tags = models.ManyToManyField(
            to="Tag",
            through='Article2Tag',
            through_fields=('article', 'tag'),
        )

        class Article2Tag(models.Model):
            nid = models.AutoField(primary_key=True)
            article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid', on_delete=models.CASCADE)
            tag = models.ForeignKey(verbose_name='標籤', to="Tag", to_field='nid', on_delete=models.CASCADE)
    db_table屬性:django自動生成關係表的名稱,不指定此值將有一個默認值

OneToOneField
    一對一關係

    related_name屬性:若是不爲OneToOneField指定related_name參數,Django將使用當前模型的小寫名稱做爲默認值。
相關文章
相關標籤/搜索