tornado項目


tornado項目之基於領域驅動模型架構設計的京東用戶管理后台

本博文將一步步揭秘京東等大型網站的領域驅動模型,致力於讓讀者完全掌握這種網絡架構中的“高富帥”。

一、預備知識:

1.接口:

python中並沒有類似java等其它語言中的接口類型,但是python中有抽象類和抽象方法。如果一個抽象類有抽象方法,那么繼承它的子類必須實現抽象類的所有方法,因此,我們基於python的抽象類和抽象方法實現接口功能。

示例代碼:

  接口示例代碼

2.依賴注入:

依賴注入的作用是將一系列無關的類通過注入參數的方式實現關聯,例如將類A的對象作為參數注入給類B,那么當調用類B的時候,類A會首先被實例化。

示例代碼:

  依賴注入示例

注:原理:首先需要明確一切事物皆對象類也是對象,類是有Type創建的,當類實例化的時候,會調用type類的call方法,call方法會調用new方法,new方法調用init方法。

二、企業級應用設計

1.總體框架目錄結構:

備注:

  • Infrastructure:一些公共組件,例如md5加密,分頁模塊,session等。
  • Model :關於數據庫的邏輯處理模塊
  • Repository :數據訪問層,包含數據庫的增刪改查
  • Service :服務層,調用Model,包含帶有規則的請求和返回
  • Statics:靜態文件目錄
  • UI層:業務處理
  • Views:模板文件
  • Application:tornado程序的起始文件
  • Config:配置文件
  • Mapper:依賴注入文件,負責整個框架不同類的依賴注入

2.首先我們從Moldel開始查看:

文件目錄:

本文主要以用戶管理為例進行介紹,因此我們來關注一下User.py文件:

代碼結構:

下面對上述代碼結構做一一介紹:

IUseRepository類:接口類,用於約束數據庫訪問類的方法
示例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class  IUseRepository:
     """
     用戶信息倉庫接口
     """
 
     def  fetch_one_by_user_pwd( self , username, password):
         """
         根據用戶名密碼獲取模型對象
         :param username: 主鍵ID
         :param password: 主鍵ID
         :return:
         """
     def  fetch_one_by_email_pwd( self , email, password):
         """
         根據郵箱密碼獲取模型對象
         :param email: 主鍵ID
         :param password: 主鍵ID
         :return:
         """
 
     def  update_last_login_by_nid( self ,nid,current_date):
         """
         根據ID更新最新登陸時間
         :param nid:
         :return:
         """

  從上述代碼可以看出,數據庫訪問類如果繼承IUseRepository類,就必須實現其中的抽象方法。

接下來的三個類,VipType、UserType、User是與用戶信息相關的類,是數據庫需要保存的數據,我們希望存入數據庫的數據格式為:nid 、username、email、last_login、user_type_id、vip_type_id,其中User類用於保存上述數據。因為user_type_id、vip_type_id存的是數字,即user_type_id、vip_type_id是外鍵,不能直接在前端進行展示,因此,我們創建了VipType、UserType類,用於根據id,獲取對應的VIP級別和用戶類型。

示例代碼:

  User類
  UserType類
  VipType類

注:VipType、UserType這兩個類獲取對應的caption均是通過類的普通特性訪問,即類似字段方式訪問。

接下來的類UserService是本py文件的重中之重,它負責調用對應的數據庫訪問類的方法,並被服務層service調用,具有承上啟下的作用:

示例代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class  UserService:
 
     def  __init__( self , user_repository):
         self .userRepository  =  user_repository
 
     def  check_login( self , username = None , email = None , password = None ):
 
         if  username:
             user_model  =  self .userRepository.fetch_one_by_user_pwd(username, password)
         else :
             user_model  =  self .userRepository.fetch_one_by_email_pwd(email, password)
         if  user_model:
             current_date  =  datetime.datetime.now()
             self .userRepository.update_last_login_by_nid(user_model.nid, current_date)
         return  user_model

  這里,我們重點介紹一下上述代碼:

初始化參數user_repository:通過依賴注入對應的數據庫訪問類的對象;

check_login:訪問數據庫的關鍵邏輯處理方法,根據用戶是用戶名+密碼方式還是郵箱加密碼的方式登錄,然后調用對應的數據庫處理方法,如果登陸成功,更新時間和最后登錄時間,最后將User類的實例返回給調用它的服務層service。(詳細見下文數據庫處理類的方法)

我們先來看一下對應的數據庫處理類中的一個方法:

1
示例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def  fetch_one_by_user_pwd( self , username, password):
        ret  =  None
        cursor  =  self .db_conn.connect()
        sql  =  """select nid,username,email,last_login,vip,user_type from UserInfo where username=%s and password=%s"""
        cursor.execute(sql, (username, password))
        db_result  =  cursor.fetchone()
        self .db_conn.close()
 
        if  db_result:
            ret  =  User(nid = db_result[ 'nid' ],
                       username = db_result[ 'username' ],
                       email = db_result[ 'email' ],
                       last_login = db_result[ 'last_login' ],
                       user_type = UserType(nid = db_result[ 'user_type' ]),
                       vip_type = VipType(nid = db_result[ 'vip' ])
                       )
        return  ret

  這里我們使用pymysql進行數據庫操作,以用戶名+密碼登陸為例,如果數據庫有對應的用戶名和密碼,將查詢結果放在User類中進行初始化,至此,ret中封裝了用戶的全部基本信息,將ret返回給上面的check_login方法,即對應上文中的返回值user_model,user_model返回給調用它的服務層service。

總結:Molde最終將封裝了用戶基本信息的User類的實例返回給服務層service。

3.接下來我們看一下服務層service:

service也是一個承上啟下的作用,它調用Moldel文件對應的數據庫業務協調方法,並被對應的UI層調用(本例中是UIadmin)。

目錄結構:

同樣的,我們只介紹User文件夾:它包含4個py文件:

  • ModelView:用於用戶前端展示的數據格式化,重點對user_type_id、vip_type_id增加對應的用戶類型和VIP級別,即將外鍵數據對應的caption放在外鍵后面,作為增加的參數。
  • Request:封裝請求Moldel文件對應數據庫協調類的參數
  • Response:封裝需要返回UI層的參數
  • Sevice:核心服務處理文件

下面對上述目錄做詳細代碼:

ModelView:

1
2
3
4
5
6
7
8
9
10
11
class  UserModelView:
 
     def  __init__( self , nid, username, email, last_login, user_type_id, user_type_caption, vip_type_id, vip_type_caption):
         self .nid  =  nid
         self .username  =  username
         self .email  =  email
         self .last_login  =  last_login
         self .user_type  =  user_type_id
         self .user_type_caption  =  user_type_caption
         self .vip_type  =  vip_type_id
         self .vip_type_caption  =  vip_type_caption

  注:對user_type_id、vip_type_id增加對應的用戶類型和VIP級別,即將外鍵數據對應的caption放在外鍵后面,作為增加的參數。

Request:

1
2
3
4
5
6
class  UserRequest:
 
     def  __init__( self , username, email, password):
         self .username  =  username
         self .email  =  email
         self .password  =  password

  Response:

1
2
3
4
5
6
class  UserResponse:
 
     def  __init__( self , status = True , message = '', model_view = None ):
         self .status  =  status     # 是否登陸成功的狀態
         self .message  =  message   #錯誤信息
         self .modelView  =  model_view   #登陸成功后的用戶數據 
UserService:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class  UserService:
 
     def  __init__( self , model_user_service):    #通過依賴注入Moldel對應的數據庫業務協調方法,此例中對應上文中的user_service
         self .modelUserService  =  model_user_service  
 
     def  check_login( self , user_request):   #核心服務層業務處理方法
         response  =  UserResponse()   #實例化返回類
 
         try :
             model  =  self .modelUserService.check_login(user_request.username, user_request.email, user_request.password)  #接收上文中的用戶基本信息,是User類的實例
             if  not  model:
                 raise  Exception( '用戶名或密碼錯誤' )
             else :    #如果登陸成功,通過UserModelView類格式化返回前端的數據
                 model_view  =  UserModelView(nid = model[ 'nid' ],
                                            username = model[ 'usename' ],
                                            email = model[ 'email' ],
                                            last_login = model[ 'last_login' ],
                                            user_type_id = model[ 'user_type' ].nid,
                                            user_type_caption = model[ 'user_type' ].caption,
                                            vip_type_id = model[ 'vip_type' ].nid,
                                            vip_type_caption = model[ 'vip_type' ].caption,)
                 response.modelView  =  model_view     #定義返回UI層的用戶信息
         except  Exception as e:
             response.status  =  False
             response.message  =  str (e)

  總結:至此,Service返回給Ui層的數據是是否登陸成功的狀態status、錯誤信息、已經格式化的用戶基本信息。

4.UI層

UI層主要負責業務處理完成后與前端的交互,它是服務層Service的調用者:

示例代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class  Login(AdminRequestHandler):
 
     def  get( self * args,  * * kwargs):
         is_login = self .session[ "is_login" ]
         current_user = ""
         if  is_login:
             current_user = self .session[ "user_info" ].username
         self .render( 'Account/Login.html' ,current_user = current_user)
 
     def  post( self * args,  * * kwargs):
         user_request = []
         #獲取用戶輸入的用戶名郵箱密碼
         user_request.append( self .get_argument( 'name' , None ))
         user_request.append( self .get_argument( 'email' , None ))
         user_request.append( self .get_argument( 'pwd' , None ))
         checkcode = self .get_argument( "checkcode" , None )
         Mapper.mapper( * user_request)
         obj = UserService.check_login()
         self .session[ "is_login" ] = True
         self .session[ "user_info" ] = obj.modelView
         self .write( "已登陸" )

 

     總結以上就是基於領域驅動模型的用戶管理后台,包含數據庫操作文件,數據庫業務處理文件,服務端文件,UI層文件。如果本文對您有參考價值

 tornado源碼系列

tornado項目之基於領域驅動模型架構設計的京東用戶管理后台
摘要: 本博文將一步步揭秘京東等大型網站的領域驅動模型,致力於讓讀者完全掌握這種網絡架構中的“高富帥”。 一、預備知識: 1.接口: python中並沒有類似java等其它語言中的接口類型,但是python中有抽象類和抽象方法。如果一個抽象類有抽象方法,那么繼承它的子類必須實現抽象類的所有方法,因此,我們基 閱讀全文

posted @ 2016-09-07 09:15 戰神王恆 閱讀(506) | 評論 (7) 編輯

tornado高效開發必備之源碼詳解
摘要: 前言:本博文重在tornado源碼剖析,相信讀者讀完此文能夠更加深入的了解tornado的運行機制,從而更加高效的使用tornado框架。 本文參考武sir博客地址:http://www.cnblogs.com/wupeiqi/tag/Tornado/ 初識tornado 首先我們從經典的hello 閱讀全文

posted @ 2016-09-01 09:10 戰神王恆 閱讀(945) | 評論 (22) 編輯

tornado web高級開發項目之抽屜官網的頁面登陸驗證、form驗證、點贊、評論、文章分頁處理、發送郵箱驗證碼、登陸驗證碼、注冊、發布文章、上傳圖片
摘要: 本博文將一步步帶領你實現抽屜官網的各種功能:包括登陸、注冊、發送郵箱驗證碼、登陸驗證碼、頁面登陸驗證、發布文章、上傳圖片、form驗證、點贊、評論、文章分頁處理以及基於tornado的后端和ajax的前端數據處理。 轉載請注明出處http://www.cnblogs.com/wanghzh/p/58 閱讀全文

posted @ 2016-08-29 09:17 戰神王恆 閱讀(1072) | 評論 (18) 編輯

Web框架之Tornado
摘要: 概述 Tornado 是 FriendFeed 使用的可擴展的非阻塞式 web 服務器及其相關工具的開源版本。這個 Web 框架看起來有些像web.py 或者 Google 的 webapp,不過為了能有效利用非阻塞式服務器環境,這個 Web 框架還包含了一些相關的有用工具 和優化。 Tornado 閱讀全文

posted @ 2016-08-25 18:41 戰神王恆 閱讀(91) | 評論 (0) 編輯

本博文將一步步揭秘京東等大型網站的領域驅動模型,致力於讓讀者完全掌握這種網絡架構中的“高富帥”。

一、預備知識:

1.接口:

python中並沒有類似java等其它語言中的接口類型,但是python中有抽象類和抽象方法。如果一個抽象類有抽象方法,那么繼承它的子類必須實現抽象類的所有方法,因此,我們基於python的抽象類和抽象方法實現接口功能。

示例代碼:

  接口示例代碼

2.依賴注入:

依賴注入的作用是將一系列無關的類通過注入參數的方式實現關聯,例如將類A的對象作為參數注入給類B,那么當調用類B的時候,類A會首先被實例化。

示例代碼:

  依賴注入示例

注:原理:首先需要明確一切事物皆對象類也是對象,類是有Type創建的,當類實例化的時候,會調用type類的call方法,call方法會調用new方法,new方法調用init方法。

二、企業級應用設計

1.總體框架目錄結構:

備注:

  • Infrastructure:一些公共組件,例如md5加密,分頁模塊,session等。
  • Model :關於數據庫的邏輯處理模塊
  • Repository :數據訪問層,包含數據庫的增刪改查
  • Service :服務層,調用Model,包含帶有規則的請求和返回
  • Statics:靜態文件目錄
  • UI層:業務處理
  • Views:模板文件
  • Application:tornado程序的起始文件
  • Config:配置文件
  • Mapper:依賴注入文件,負責整個框架不同類的依賴注入

2.首先我們從Moldel開始查看:

文件目錄:

本文主要以用戶管理為例進行介紹,因此我們來關注一下User.py文件:

代碼結構:

下面對上述代碼結構做一一介紹:

IUseRepository類:接口類,用於約束數據庫訪問類的方法
示例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class  IUseRepository:
     """
     用戶信息倉庫接口
     """
 
     def  fetch_one_by_user_pwd( self , username, password):
         """
         根據用戶名密碼獲取模型對象
         :param username: 主鍵ID
         :param password: 主鍵ID
         :return:
         """
     def  fetch_one_by_email_pwd( self , email, password):
         """
         根據郵箱密碼獲取模型對象
         :param email: 主鍵ID
         :param password: 主鍵ID
         :return:
         """
 
     def  update_last_login_by_nid( self ,nid,current_date):
         """
         根據ID更新最新登陸時間
         :param nid:
         :return:
         """

  從上述代碼可以看出,數據庫訪問類如果繼承IUseRepository類,就必須實現其中的抽象方法。

接下來的三個類,VipType、UserType、User是與用戶信息相關的類,是數據庫需要保存的數據,我們希望存入數據庫的數據格式為:nid 、username、email、last_login、user_type_id、vip_type_id,其中User類用於保存上述數據。因為user_type_id、vip_type_id存的是數字,即user_type_id、vip_type_id是外鍵,不能直接在前端進行展示,因此,我們創建了VipType、UserType類,用於根據id,獲取對應的VIP級別和用戶類型。

示例代碼:

  User類
  UserType類
  VipType類

注:VipType、UserType這兩個類獲取對應的caption均是通過類的普通特性訪問,即類似字段方式訪問。

接下來的類UserService是本py文件的重中之重,它負責調用對應的數據庫訪問類的方法,並被服務層service調用,具有承上啟下的作用:

示例代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class  UserService:
 
     def  __init__( self , user_repository):
         self .userRepository  =  user_repository
 
     def  check_login( self , username = None , email = None , password = None ):
 
         if  username:
             user_model  =  self .userRepository.fetch_one_by_user_pwd(username, password)
         else :
             user_model  =  self .userRepository.fetch_one_by_email_pwd(email, password)
         if  user_model:
             current_date  =  datetime.datetime.now()
             self .userRepository.update_last_login_by_nid(user_model.nid, current_date)
         return  user_model

  這里,我們重點介紹一下上述代碼:

初始化參數user_repository:通過依賴注入對應的數據庫訪問類的對象;

check_login:訪問數據庫的關鍵邏輯處理方法,根據用戶是用戶名+密碼方式還是郵箱加密碼的方式登錄,然后調用對應的數據庫處理方法,如果登陸成功,更新時間和最后登錄時間,最后將User類的實例返回給調用它的服務層service。(詳細見下文數據庫處理類的方法)

我們先來看一下對應的數據庫處理類中的一個方法:

1
示例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def  fetch_one_by_user_pwd( self , username, password):
        ret  =  None
        cursor  =  self .db_conn.connect()
        sql  =  """select nid,username,email,last_login,vip,user_type from UserInfo where username=%s and password=%s"""
        cursor.execute(sql, (username, password))
        db_result  =  cursor.fetchone()
        self .db_conn.close()
 
        if  db_result:
            ret  =  User(nid = db_result[ 'nid' ],
                       username = db_result[ 'username' ],
                       email = db_result[ 'email' ],
                       last_login = db_result[ 'last_login' ],
                       user_type = UserType(nid = db_result[ 'user_type' ]),
                       vip_type = VipType(nid = db_result[ 'vip' ])
                       )
        return  ret

  這里我們使用pymysql進行數據庫操作,以用戶名+密碼登陸為例,如果數據庫有對應的用戶名和密碼,將查詢結果放在User類中進行初始化,至此,ret中封裝了用戶的全部基本信息,將ret返回給上面的check_login方法,即對應上文中的返回值user_model,user_model返回給調用它的服務層service。

總結:Molde最終將封裝了用戶基本信息的User類的實例返回給服務層service。

3.接下來我們看一下服務層service:

service也是一個承上啟下的作用,它調用Moldel文件對應的數據庫業務協調方法,並被對應的UI層調用(本例中是UIadmin)。

目錄結構:

同樣的,我們只介紹User文件夾:它包含4個py文件:

  • ModelView:用於用戶前端展示的數據格式化,重點對user_type_id、vip_type_id增加對應的用戶類型和VIP級別,即將外鍵數據對應的caption放在外鍵后面,作為增加的參數。
  • Request:封裝請求Moldel文件對應數據庫協調類的參數
  • Response:封裝需要返回UI層的參數
  • Sevice:核心服務處理文件

下面對上述目錄做詳細代碼:

ModelView:

1
2
3
4
5
6
7
8
9
10
11
class  UserModelView:
 
     def  __init__( self , nid, username, email, last_login, user_type_id, user_type_caption, vip_type_id, vip_type_caption):
         self .nid  =  nid
         self .username  =  username
         self .email  =  email
         self .last_login  =  last_login
         self .user_type  =  user_type_id
         self .user_type_caption  =  user_type_caption
         self .vip_type  =  vip_type_id
         self .vip_type_caption  =  vip_type_caption

  注:對user_type_id、vip_type_id增加對應的用戶類型和VIP級別,即將外鍵數據對應的caption放在外鍵后面,作為增加的參數。

Request:

1
2
3
4
5
6
class  UserRequest:
 
     def  __init__( self , username, email, password):
         self .username  =  username
         self .email  =  email
         self .password  =  password

  Response:

1
2
3
4
5
6
class  UserResponse:
 
     def  __init__( self , status = True , message = '', model_view = None ):
         self .status  =  status     # 是否登陸成功的狀態
         self .message  =  message   #錯誤信息
         self .modelView  =  model_view   #登陸成功后的用戶數據 
UserService:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class  UserService:
 
     def  __init__( self , model_user_service):    #通過依賴注入Moldel對應的數據庫業務協調方法,此例中對應上文中的user_service
         self .modelUserService  =  model_user_service  
 
     def  check_login( self , user_request):   #核心服務層業務處理方法
         response  =  UserResponse()   #實例化返回類
 
         try :
             model  =  self .modelUserService.check_login(user_request.username, user_request.email, user_request.password)  #接收上文中的用戶基本信息,是User類的實例
             if  not  model:
                 raise  Exception( '用戶名或密碼錯誤' )
             else :    #如果登陸成功,通過UserModelView類格式化返回前端的數據
                 model_view  =  UserModelView(nid = model[ 'nid' ],
                                            username = model[ 'usename' ],
                                            email = model[ 'email' ],
                                            last_login = model[ 'last_login' ],
                                            user_type_id = model[ 'user_type' ].nid,
                                            user_type_caption = model[ 'user_type' ].caption,
                                            vip_type_id = model[ 'vip_type' ].nid,
                                            vip_type_caption = model[ 'vip_type' ].caption,)
                 response.modelView  =  model_view     #定義返回UI層的用戶信息
         except  Exception as e:
             response.status  =  False
             response.message  =  str (e)

  總結:至此,Service返回給Ui層的數據是是否登陸成功的狀態status、錯誤信息、已經格式化的用戶基本信息。

4.UI層

UI層主要負責業務處理完成后與前端的交互,它是服務層Service的調用者:

示例代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class  Login(AdminRequestHandler):
 
     def  get( self * args,  * * kwargs):
         is_login = self .session[ "is_login" ]
         current_user = ""
         if  is_login:
             current_user = self .session[ "user_info" ].username
         self .render( 'Account/Login.html' ,current_user = current_user)
 
     def  post( self * args,  * * kwargs):
         user_request = []
         #獲取用戶輸入的用戶名郵箱密碼
         user_request.append( self .get_argument( 'name' , None ))
         user_request.append( self .get_argument( 'email' , None ))
         user_request.append( self .get_argument( 'pwd' , None ))
         checkcode = self .get_argument( "checkcode" , None )
         Mapper.mapper( * user_request)
         obj = UserService.check_login()
         self .session[ "is_login" ] = True
         self .session[ "user_info" ] = obj.modelView
         self .write( "已登陸" )

 

     總結以上就是基於領域驅動模型的用戶管理后台,包含數據庫操作文件,數據庫業務處理文件,服務端文件,UI層文件。如果本文對您有參考價值


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM