django ORM

Object Relational Mapping(ORM)

ORM介紹

ORM概念

對象關係映射(Object Relational Mapping,簡稱ORM)模式是一種爲了解決面向對象與關係數據庫存在的互不匹配的現象的技術。mysql

簡單的說,ORM是經過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關係數據庫中。程序員

ORM在業務邏輯層和數據庫層之間充當了橋樑的做用。sql

ORM由來

讓咱們從O/R開始。字母O起源於"對象"(Object),而R則來自於"關係"(Relational)。數據庫

幾乎全部的軟件開發過程當中都會涉及到對象和關係數據庫。在用戶層面和業務邏輯層面,咱們是面向對象的。當對象的信息發生變化的時候,咱們就須要把對象的信息保存在關係數據庫中。django

按照以前的方式來進行開發就會出現程序員會在本身的業務邏輯代碼中夾雜不少SQL語句用來增長、讀取、修改、刪除相關數據,而這些代碼一般都是重複的。後端

ORM的優點

ORM解決的主要問題是對象和關係的映射。它一般把一個類和一個表一一對應,類的每一個實例對應表中的一條記錄,類的每一個屬性對應表中的每一個字段。 app

ORM提供了對數據庫的映射,不用直接編寫SQL代碼,只需像操做對象同樣從數據庫操做數據。ide

讓軟件開發人員專一於業務邏輯的處理,提升了開發效率。工具

ORM的劣勢

ORM的缺點是會在必定程度上犧牲程序的執行效率。spa

ORM用多了SQL語句就不會寫了,關係數據庫相關技能退化...

ORM總結

ORM只是一種工具,工具確實能解決一些重複,簡單的勞動。這是不能否認的。

但咱們不能期望某個工具能一勞永逸地解決全部問題,一些特殊問題仍是須要特殊處理的。

可是在整個軟件開發過程當中須要特殊處理的狀況應該都是不多的,不然所謂的工具也就失去了它存在的意義。

Django中的ORM

Django項目使用MySQL數據庫

1. 在Django項目的settings.py文件中,配置數據庫鏈接信息:

複製代碼
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "你的數據庫名稱",  # 須要本身手動建立數據庫
        "USER": "數據庫用戶名",
        "PASSWORD": "數據庫密碼",
        "HOST": "數據庫IP",
        "POST": 3306
    }
}
複製代碼

2. 在Django項目的__init__.py文件中寫以下代碼,告訴Django使用pymysql模塊鏈接MySQL數據庫:

import pymysql

pymysql.install_as_MySQLdb()

Model

在Django中model是你數據的單1、明確的信息來源。它包含了你存儲的數據的重要字段和行爲。一般,一個模型(model)映射到一個數據庫表,

基本狀況:

  • 每一個模型都是一個Python類,它是django.db.models.Model的子類。
  • 模型的每一個屬性都表明一個數據庫字段。
  • 綜上所述,Django爲您提供了一個自動生成的數據庫訪問API,詳詢官方文檔連接

 

快速入門 

下面這個例子定義了一個 Person 模型,包含 first_name 和 last_name

from django.db import models

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

first_name 和 last_name 是模型的字段。每一個字段被指定爲一個類屬性,每一個屬性映射到一個數據庫列。

上面的 Person 模型將會像這樣建立一個數據庫表:

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

一些說明:

  • 表myapp_person的名稱是自動生成的,若是你要自定義表名,須要在model的Meta類中指定 db_table 參數,強烈建議使用小寫表名,特別是使用MySQL做爲後端數據庫時。
  • id字段是自動添加的,若是你想要指定自定義主鍵,只需在其中一個字段中指定 primary_key=True 便可。若是Django發現你已經明確地設置了Field.primary_key,它將不會添加自動ID列。
  • 本示例中的CREATE TABLE SQL使用PostgreSQL語法進行格式化,但值得注意的是,Django會根據配置文件中指定的數據庫後端類型來生成相應的SQL語句。
  • Django支持MySQL5.5及更高版本。

Django ORM 經常使用字段和參數

經常使用字段

AutoField

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

IntegerField

一個整數類型,範圍在 -2147483648 to 2147483647。

CharField

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

DateField

日期字段,日期格式  YYYY-MM-DD,至關於Python中的datetime.date()實例。    ##這個只有年月日

DateTimeField

日期時間字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],至關於Python中的datetime.datetime()實例。     ##這個是帶時間的  須要有auto_now_add=TRue 須要或者參數,在添加數據的時候,這個值把當前的時候存進去

字段合集(爭取記憶)

  字段合集

自定義字段(瞭解爲主)

class UnsignedIntegerField(models.IntegerField):
    def db_type(self, connection):
        return 'integer UNSIGNED'

自定義char類型字段:

複製代碼
class FixedCharField(models.Field):
    """
    自定義的char類型的字段類
    """
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        super(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)
複製代碼

建立的表結構:

附ORM字段與數據庫實際字段的對應關係

  對應關係

字段參數

null

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

unique

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

db_index

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

default

爲該字段設置默認值。

DateField和DateTimeField

auto_now_add

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

auto_now

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

 

關係字段

ForeignKey

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

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

字段參數

to

設置要關聯的表

to_field

設置要關聯的表的字段

related_name

反向操做時,使用的字段名,用於代替原反向查詢時的'表名_set'。

例如:

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

class Student(models.Model):
    name = models.CharField(max_length=32)
    theclass = models.ForeignKey(to="Classes")

當咱們要查詢某個班級關聯的全部學生(反向查詢)時,咱們會這麼寫:

models.Classes.objects.first().student_set.all()

當咱們在ForeignKey字段中添加了參數 related_name 後,

class Student(models.Model):
    name = models.CharField(max_length=32)
    theclass = models.ForeignKey(to="Classes", related_name="students")

當咱們要查詢某個班級關聯的全部學生(反向查詢)時,咱們會這麼寫:

models.Classes.objects.first().students.all()

related_query_name

反向查詢操做時,使用的鏈接前綴,用於替換表名。

on_delete

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

models.CASCADE
刪除關聯數據,與之關聯也刪除


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)
    )
複製代碼

db_constraint

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

OneToOneField

一對一字段。

一般一對一字段用來擴展已有字段。

字段參數

to

設置要關聯的表。

to_field

設置要關聯的字段。

on_delete

同ForeignKey字段。

ManyToManyField

用於表示多對多的關聯關係。在數據庫中經過第三張表來創建關聯關係。

##第三張表的好處是能夠爲之後增長一些信息更方便。

##第三張表須要指定外鍵這樣才能夠

## 第三張表的字段名字不能加id

 

字段參數

to

設置要關聯的表

related_name

同ForeignKey字段。

related_query_name

同ForeignKey字段。

symmetrical

僅用於多對多自關聯時,指定內部是否建立反向操做的字段。默認爲True。

舉個例子:

class Person(models.Model):
    name = models.CharField(max_length=16)
    friends = models.ManyToManyField("self")

此時,person對象就沒有person_set屬性。

class Person(models.Model):
    name = models.CharField(max_length=16)
    friends = models.ManyToManyField("self", symmetrical=False)

此時,person對象如今就可使用person_set屬性進行反向查詢。

through

在使用ManyToManyField字段時,Django將自動生成一張表來管理多對多的關聯關係。

但咱們也能夠手動建立第三張表來管理多對多關係,此時就須要經過through來指定第三張表的表名。

through_fields

設置關聯的字段。   ##這個是在手動建立第三張表,有了Book2Author這個類之後才使用這個參數。

class Book(models.Model):
    title = models.CharField(max_length=32)


class Author(models.Model):
    name = models.CharField(max_length=32)
    #
    books = models.ManyToManyField(
        to="Book",
        through="Book2Author",
        through_fields=('author', 'book')
    )


# 本身建立第三張表
class Book2Author(models.Model):
    id = models.AutoField(primary_key=True)
    book = models.ForeignKey(to=Book)
    author = models.ForeignKey(to=Author)
    first_blood = models.DateField()
代碼

 

db_table

默認建立第三張表時,數據庫中表的名稱。

元信息

ORM對應的類裏面包含另外一個Meta類,而Meta類封裝了一些數據庫的信息。主要字段以下:

db_table

ORM在數據庫中的表名默認是 app_類名,能夠經過db_table能夠重寫表名。

index_together

聯合索引。

unique_together

聯合惟一索引。

ordering

指定默認按什麼字段排序。

只有設置了該屬性,咱們查詢到的結果才能夠被reverse()。

相關文章
相關標籤/搜索