Django的核心思想ORM

元類實現ORM

1. ORM是什么

ORM 是 python編程語言后端web框架 Django的核心思想,“Object Relational Mapping”,即對象-關系映射,簡稱ORM。

一個句話理解就是:創建一個實例對象,用創建它的類名當做數據表名,用創建它的類屬性對應數據表的字段,當對這個實例對象操作時,能夠對應MySQL語句

demo:

class User(父類省略):uid = ('uid', "int unsigned")name = ('username', "varchar(30)")email = ('email', "varchar(30)")password = ('password', "varchar(30)")...省略...u = User(uid=12345, name='Michael', email='test@orm.org', password='my-pwd')
u.save()
# 對應如下sql語句
# insert into User (username,email,password,uid)
# values ('Michael','test@orm.org','my-pwd',12345)

說明

  1. 所謂的ORM就是讓開發者在操作數據庫的時候,能夠像操作對象時通過xxxx.屬性=yyyy一樣簡單,這是開發ORM的初衷
  2. 只不過ORM的實現較為復雜,Django中已經實現了 很復雜的操作,本節知識 主要通過完成一個 insert相類似的ORM,理解其中的道理就就可以了

2. 通過元類簡單實現ORM中的insert功能

class ModelMetaclass(type):def __new__(cls, name, bases, attrs):mappings = dict()# 判斷是否需要保存for k, v in attrs.items():# 判斷是否是指定的StringField或者IntegerField的實例對象if isinstance(v, tuple):print('Found mapping: %s ==> %s' % (k, v))mappings[k] = v# 刪除這些已經在字典中存儲的屬性for k in mappings.keys():attrs.pop(k)# 將之前的uid/name/email/password以及對應的對象引用、類名字attrs['__mappings__'] = mappings  # 保存屬性和列的映射關系attrs['__table__'] = name  # 假設表名和類名一致return type.__new__(cls, name, bases, attrs)class User(metaclass=ModelMetaclass):uid = ('uid', "int unsigned")name = ('username', "varchar(30)")email = ('email', "varchar(30)")password = ('password', "varchar(30)")# 當指定元類之后,以上的類屬性將不在類中,而是在__mappings__屬性指定的字典中存儲# 以上User類中有 # __mappings__ = {#     "uid": ('uid', "int unsigned")#     "name": ('username', "varchar(30)")#     "email": ('email', "varchar(30)")#     "password": ('password', "varchar(30)")# }# __table__ = "User"def __init__(self, **kwargs):for name, value in kwargs.items():setattr(self, name, value)def save(self):fields = []args = []for k, v in self.__mappings__.items():fields.append(v[0])args.append(getattr(self, k, None))sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join([str(i) for i in args]))print('SQL: %s' % sql)u = User(uid=12345, name='Michael', email='test@orm.org', password='my-pwd')
# print(u.__dict__)
u.save()

執行的效果:(sql語句中缺少單引號)

Found mapping: password ==> ('password', 'varchar(30)')
Found mapping: email ==> ('email', 'varchar(30)')
Found mapping: uid ==> ('uid', 'int unsigned')
Found mapping: name ==> ('username', 'varchar(30)')
SQL: insert into User (uid,password,username,email) values (12345,my-pwd,Michael,test@orm.org)

3. 完善對數據類型的檢測

class ModelMetaclass(type):def __new__(cls, name, bases, attrs):mappings = dict()# 判斷是否需要保存for k, v in attrs.items():# 判斷是否是指定的StringField或者IntegerField的實例對象if isinstance(v, tuple):print('Found mapping: %s ==> %s' % (k, v))mappings[k] = v# 刪除這些已經在字典中存儲的屬性for k in mappings.keys():attrs.pop(k)# 將之前的uid/name/email/password以及對應的對象引用、類名字attrs['__mappings__'] = mappings  # 保存屬性和列的映射關系attrs['__table__'] = name  # 假設表名和類名一致return type.__new__(cls, name, bases, attrs)class User(metaclass=ModelMetaclass):uid = ('uid', "int unsigned")name = ('username', "varchar(30)")email = ('email', "varchar(30)")password = ('password', "varchar(30)")# 當指定元類之后,以上的類屬性將不在類中,而是在__mappings__屬性指定的字典中存儲# 以上User類中有 # __mappings__ = {#     "uid": ('uid', "int unsigned")#     "name": ('username', "varchar(30)")#     "email": ('email', "varchar(30)")#     "password": ('password', "varchar(30)")# }# __table__ = "User"def __init__(self, **kwargs):for name, value in kwargs.items():setattr(self, name, value)def save(self):fields = []args = []for k, v in self.__mappings__.items():fields.append(v[0])args.append(getattr(self, k, None))args_temp = list()for temp in args:# 判斷入如果是數字類型if isinstance(temp, int):args_temp.append(str(temp))elif isinstance(temp, str):args_temp.append("""'%s'""" % temp)sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(args_temp))print('SQL: %s' % sql)u = User(uid=12345, name='Michael', email='test@orm.org', password='my-pwd')
# print(u.__dict__)
u.save()

運行效果如下:

Found mapping: uid ==> ('uid', 'int unsigned')
Found mapping: password ==> ('password', 'varchar(30)')
Found mapping: name ==> ('username', 'varchar(30)')
Found mapping: email ==> ('email', 'varchar(30)')
SQL: insert into User (email,uid,password,username) values ('test@orm.org',12345,'my-pwd','Michael')

4. 抽取到基類中

class ModelMetaclass(type):def __new__(cls, name, bases, attrs):mappings = dict()# 判斷是否需要保存for k, v in attrs.items():# 判斷是否是指定的StringField或者IntegerField的實例對象if isinstance(v, tuple):print('Found mapping: %s ==> %s' % (k, v))mappings[k] = v# 刪除這些已經在字典中存儲的屬性for k in mappings.keys():attrs.pop(k)# 將之前的uid/name/email/password以及對應的對象引用、類名字attrs['__mappings__'] = mappings  # 保存屬性和列的映射關系attrs['__table__'] = name  # 假設表名和類名一致return type.__new__(cls, name, bases, attrs)class Model(object, metaclass=ModelMetaclass):def __init__(self, **kwargs):for name, value in kwargs.items():setattr(self, name, value)def save(self):fields = []args = []for k, v in self.__mappings__.items():fields.append(v[0])args.append(getattr(self, k, None))args_temp = list()for temp in args:# 判斷入如果是數字類型if isinstance(temp, int):args_temp.append(str(temp))elif isinstance(temp, str):args_temp.append("""'%s'""" % temp)sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(args_temp))print('SQL: %s' % sql)class User(Model):uid = ('uid', "int unsigned")name = ('username', "varchar(30)")email = ('email', "varchar(30)")password = ('password', "varchar(30)")u = User(uid=12345, name='Michael', email='test@orm.org', password='my-pwd')
# print(u.__dict__)
u.save()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/456717.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/456717.shtml
英文地址,請注明出處:http://en.pswp.cn/news/456717.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Secondary Namenode的Check point機制以及Namenode、Datanode工作機制說明

目錄前言:1、NameNode的工作機制2、DataNode的工作機制3、Secondary Namenode的Check point機制 目錄 前言: 在說明checkpoint機制之前,先要了解下namenode、datanode的一些功能和職責。 1、NameNode的工作機制 問題場景: 1…

表單驗證的初步實現和省市級聯

1.表單驗證的初步實現 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html xmlns"http://www.w3.org/1999/xhtml" lang"en"><head><meta http-equiv"Conte…

抓包軟件:Charles

修正&#xff1a;手機不必一定連接電腦分享的熱點&#xff0c;只需要手機和電腦在同一個局域網下就可以了&#xff0c;手機代理IP設置為電腦的IP。 之前寫過一篇通過Wireshark進行抓包&#xff0c;分析網絡連接的文章《通過WireShark抓取iOS聯網數據實例分析》&#xff1a;htt…

Hive的相關介紹

目錄前言&#xff1a;1、Hive簡介2、Hive架構3、Hive與Hadoop的關系4、Hive與傳統數據庫對比5、Hive的數據存儲總結&#xff1a; 目錄 前言&#xff1a; 為什么使用Hive 直接使用hadoop所面臨的問題 人員學習成本太高 項目周期要求太短 MapReduce實現復雜查詢邏輯開發難…

數據結構實驗之排序七:選課名單

數據結構實驗之排序七&#xff1a;選課名單 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 隨著學校規模的擴大&#xff0c;學生人數急劇增加&#xff0c;選課名單的輸出也成為一個繁重的任務&#xff0c;我校目前有在校生3萬多名&#xff0…

Java第五次作業--面向對象高級特性(抽象類和接口)

一、學習要點 認真看書并查閱相關資料&#xff0c;掌握以下內容&#xff1a; 掌握抽象類的設計掌握接口的設計理解簡單工廠設計模式理解抽象類和接口的區別掌握包裝類的應用掌握對象的比較方法和比較器的使用學習使用日期操作類學習匿名內部類的使用二、作業要求 發布一篇隨筆&…

關于國內廠商的國際版殺毒軟件

很多國內軟件公司的殺毒軟件都分為國內版和國際版&#xff0c;這二者有什么區別呢&#xff1f; 首先&#xff0c;這兩個的團隊是不一樣的。國際版的團隊大多收購&#xff0c;國內版為自研。例如百度殺毒的國際版就是原超級巡警的團隊做的&#xff0c;而國內版是自己另起爐灶。…

gulp教程之gulp-minify-css【gulp-clean-css】

原文&#xff1a;http://www.ydcss.com/archives/41 簡介&#xff1a; 使用gulp-minify-css壓縮css文件&#xff0c;減小文件大小&#xff0c;并給引用url添加版本號避免緩存。重要&#xff1a;gulp-minify-css已經被廢棄&#xff0c;請使用gulp-clean-css&#xff0c;用法一致…

大數據面試題總結(附答案)

文章目錄前言hadoop相關試題Hive相關試題Hbase相關試題Storm相關試題Spark相關試題Java基礎試題其他前言 最近由于要準備面試就開始提早看些面試、筆試題。以下是自己總結的一些經常出現、有價值的試題&#xff0c;包含hadoop、hive、hbase、storm、spark等。答案僅供參考&…

win7 IE11卸載后無法上網

今天某同事需要訪問一個銀行網站&#xff0c;必須使用IE8,我在win7中降級IE11,直接卸載了IE11和其語言包&#xff0c;發現IE8再也打不開網頁了&#xff0c;每次打開都提示保存html網頁。測試Google Chrome上網完全沒有問題。IE8的internet選項等任何工具菜單點擊均無反應&#…

關于django的模板

模板 問題 如何向請求者返回一個漂亮的頁面呢&#xff1f; 肯定需要用到html、css&#xff0c;如果想要更炫的效果還要加入js&#xff0c;問題來了&#xff0c;這么一堆字段串全都寫到視圖中&#xff0c;作為HttpResponse()的參數嗎&#xff1f;這樣定義就太麻煩了吧&#x…

Hbase簡介及常用命令相關知識總結

文章目錄目錄前言&#xff1a;1.Hbase簡介1.1、什么是Hbase1.2、與傳統數據庫的對比1.3、Hbase集群中的角色2、Hbase數據模型3、Hbase命令總結&#xff1a;目錄 前言&#xff1a; 對于Hbase來說&#xff0c;由于其是基于列的數據庫&#xff0c;所以比傳統的數據庫快許多&…

Django中模型類 屬性-學習筆記

定義屬性 Django根據屬性的類型確定以下信息&#xff1a; 當前選擇的數據庫支持字段的類型渲染管理表單時使用的默認html控件在管理站點最低限度的驗證 django會為表創建自動增長的主鍵列&#xff0c;每個模型只能有一個主鍵列&#xff0c;如果使用選項設置某屬性為主鍵列后d…

Angular Redux

Angular Redux 轉載于:https://www.cnblogs.com/skating/p/6185878.html

AtomicInteger相關類

在java6以后我們不但接觸到了Lock相關的鎖&#xff0c;也接觸到了很多更加樂觀的原子修改操作&#xff0c;也就是在修改時我們只需要保證它的那個瞬間是安全的即可&#xff0c;經過相應的包裝后可以再處理對象的并發修改&#xff0c;以及并發中的ABA問題&#xff0c;本文講述At…

Storm入門簡介

目錄前言&#xff1a;1、Storm簡介2、Storm與Hadoop的區別3、Storm核心組件4、Storm編程模型5、流式計算一般架構圖&#xff08;重要&#xff09;總結&#xff1a; 目錄 前言&#xff1a; 在介紹Storm之前&#xff0c;先介紹下離線計算。 離線計算&#xff1a;批量獲取數據…

項目完成

完成示例項目 現在還需要的代碼包括三個方面&#xff0c;三個方面順序不分先后。 1.定義視圖2.定義URLconf3.定義模板 定義視圖 編寫booktest/views.py文件如下&#xff1a; from django.shortcuts import render from booktest.models import BookInfo#首頁&#xff0c;展…

前端模板預編譯技術

什么是前端模板預編譯 前端模板預編譯通過預編譯技術讓前端模板突破瀏覽器限制&#xff0c;實現后端模板一樣的同步“文件”加載能力。它采用目錄來組織維護前端模板&#xff0c;從而讓前端模板實現工程化管理&#xff0c;最終保證前端模板在復雜單頁 web 應用下的可維護性。同…

Python如何生成windows可執行的exe文件

打包工具 pyinstaller 安裝pyinstaller 如果你的網絡穩定&#xff0c;通常直接使用下面的命令安裝即可&#xff1a; pip install pyinstaller 當然了&#xff0c;你也可以下載pyinstaller源碼包&#xff0c;然后進入包目錄執行下面的命令&#xff0c;同樣可以安裝&#xff…

招商銀行信用卡中心華泰證券暑期實習軟開筆試小結

白菜自動化小碩一枚&#xff0c;18屆&#xff0c;下學期就正式要找工作了&#xff0c;沒有實習經驗&#xff0c;感覺心慌慌。現在學校里已經開始各種提前招實習&#xff0c;內推了&#xff0c;so暑假想提前試試水&#xff0c;投一投暑期實習。 看到心水的單位就投一投&#xff…