小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

【Python之路】特別篇

 highoo 2019-03-20
登陸與注冊

注冊功能:

流程: 填寫用戶名,郵箱,獲取郵箱驗證碼,填入密碼 單擊<下一步>按鈕,完成注冊!

1.獲取郵箱驗證碼(具體步驟分析):

1.利用ajax 往后臺傳入郵箱,

2.后臺表單驗證,郵箱填寫是否正確,     

  => 成功,則繼續(xù)3,

  => 錯誤,寫入錯誤信息,頁面輸出錯誤提示!

3.查詢sendcode 數(shù)據(jù)庫表,查詢該郵箱是否是第一次發(fā)送驗證碼

  => 第一次發(fā)送: 數(shù)據(jù)表中插入記錄 (郵箱,發(fā)送次數(shù)1,郵箱驗證碼,狀態(tài)1,有效時間:當前時間-1小時)

  => 否則: 從數(shù)據(jù)表中查詢出該郵箱驗證碼發(fā)送次數(shù),

      => 如果 >5 則,再判斷上次發(fā)送時間+1小時 是否大于當前時間!

          => 大于當前時間,則發(fā)送驗證碼,修改數(shù)據(jù)表記錄 (發(fā)送次數(shù)+1,郵箱驗證碼,有效時間)

                            => 小于當前時間,則為多次惡意發(fā)送,不操作,寫入錯誤信息,需要等待1小時,

                 => 如果<5 則直接發(fā)送驗證碼,修改數(shù)據(jù)表記錄 (發(fā)送次數(shù)+1,郵箱驗證碼,有效時間)

4.json信息返回。

SendEmailCodeHandler
commons.py 公共方法:生成4位驗證碼
前端JQ:發(fā)送驗證碼

2.驗證碼發(fā)送過程: 頁面倒計時

原理:設(shè)計計時器,每1秒修改1次text值, 時間小于0時,取消計時器

前端JQ:倒計時

3.賬號注冊 

1.JQ獲取前臺輸入表單內(nèi)容

2.ajax傳輸給后臺,建立表單驗證

  => 正確,繼續(xù)3

  => 錯誤,返回錯誤信息,頁面顯示錯誤信息

3.數(shù)據(jù)庫中查詢用戶郵箱是否存在

  => 不存在,插入數(shù)據(jù)庫,繼續(xù)4

  => 存在,返回錯誤信息,頁面顯示

4.注冊賬號完成,寫入session,注冊完成頁面刷新實現(xiàn)自動登錄

前端JQ:獲取輸入值
RegisterUserHandler

表單錯誤時,頁面信息提示(效果圖):

登錄功能:

原理:與注冊功能類似

1.圖片驗證碼:點擊驗證碼,自動更改

驗證碼為后臺生成的圖片,每點擊一次,src地址后面 多加?實現(xiàn)切換

<div class="inp-block">
    <input type="text" name="phoneregister" placeholder="請輸入驗證碼" id="u-code" class="phonenum"  autocomplete="off"/>
    <img src="/check_code" onclick='ChangeCode();' id='imgCode' class="codeimg">
</div>
前端JQ:點擊改變驗證碼
前端JQ:登錄按鈕
CheckcodeHandler
LoginUserHandler
check_code.py
表單驗證

設(shè)計思想: 無論表單通過form形式,或者ajax形式,發(fā)送數(shù)據(jù)給后端,我們都要先通過:某些規(guī)則進行過濾和驗證,再對其進行數(shù)據(jù)的插入,修改等操作

實現(xiàn)思路:1,有form表單數(shù)據(jù)來臨時,初始化一個表單類,傳入self;

     2,自動獲取form上數(shù)據(jù)字段,self.get_arguments(name),name與前端input標簽的name名字一一對應(yīng);

     3,通過表單類,調(diào)用檢測方法 check_value(),

     4,如果form表單數(shù)據(jù),符合自定義的規(guī)則,以字典形式返回數(shù)據(jù),{ ‘前端input的name值’:‘input的value值’ } =》 存儲在表單類的 self._value_dict 中

     5,如果form表單數(shù)據(jù),不符合自定義的規(guī)則,以字典形式返回錯誤信息,{ ‘前端input的name值’:‘錯誤信息’ } =》 存儲在表單類的 self._error_dict 中

 

1. 定義一個表單類 LoginForm ,__init__方法中對象名為 前端input標簽的name值

   required 是否可以為空值, error_dict 定義錯誤信息輸出內(nèi)容

復(fù)制代碼
class LoginForm(BaseForm):
    def __init__(self):
        self.username = UsernameField(required=True,error_dict={'required':'用戶名不能為空' , 'valid':'用戶名錯誤'})
        self.password = PasswordField(required=True,error_dict={'required':'密碼不能為空' , 'valid':'用戶名或密碼錯誤'})
        self.code = CodeField(required=True,error_dict={'required':'驗證碼不能為空' , 'valid':'驗證碼錯誤'})
        self.remember = CheckBoxField(required=False,error_dict={'valid':'格式錯誤'})
        super(LoginForm, self).__init__()
復(fù)制代碼

2. 繼承BaseForm類,該類初始化了,當前Form表單共用的最后返回數(shù)據(jù)和錯誤信息的字典對象

復(fù)制代碼
class BaseForm():
    def __init__(self):
        self._value_dict = {}
        self._error_dict = {}
        self._valid_status = True
    
    def check_value(self):
        ....
復(fù)制代碼

  check_value() 執(zhí)行獲取前端輸入的數(shù)據(jù),self.get_argument(xxxx) 并且根據(jù)每個input標簽定義的規(guī)則去驗證數(shù)據(jù)的正確性 (上文的UsernameField,PasswordField..等)

  通過self.__dict__循環(huán)獲取LoginForm的成員對象,調(diào)用Field的validate()方法,驗證Form表單中每一個的值。驗證正確,信息存儲在self._value_dict 中, 錯誤信息存儲在self._error_dict 中

復(fù)制代碼
def check_value(self,handler):
    for key,regular in self.__dict__.items():
        input_value = handler.get_argument(key,None)
        regular.validate(key,input_value)
    if regular.is_valid:
        self._value_dict[key] = regular.value
    else:
        self._error_dict[key] = regular.error
復(fù)制代碼
BaseForm 完整代碼

3. Field 自定義的規(guī)則類

  為前端input標簽,定義不同的驗證規(guī)則(正則表達式),驗證用戶輸入的數(shù)據(jù)

復(fù)制代碼
class PasswordField(Field):
    REGULAR = "[0-9 | A-Z | a-z]{6,16}"
    def __init__(self,required=True,error_dict=None):

        self.error_dict = {}   #錯誤信息
        if error_dict:
            self.error_dict.update(error_dict)   #用戶自定義的錯誤信息

        self.required = required
        super(PasswordField, self).__init__()
復(fù)制代碼

   繼承父類Field,初始化存儲信息的成員

復(fù)制代碼
class Field:

    def __init__(self):
        self.is_valid = False   # 驗證規(guī)則是否通過,默認False
        self.name = None
        self.value = None      # 獲取的前端input值
        self.error = None

    def validate(self, name, input_value):
        ...
復(fù)制代碼

    執(zhí)行validate()方法,

  1.先判斷該值是否允許為空?,

    => 可以為空,驗證通過,self.value = input輸入值

    => 不可以為空, 判斷 input輸入值 是否為空?

        => input輸入值為空,self.error = 定義的錯誤信息(required)

        => 不為空,繼續(xù)正則表達式判斷,re.match(REGULAR,input_value)

            => 正則通過,self.value = input輸入值, self.is_valid = True

            => 正則不通過, self.error = 定義的錯誤信息(valid)

Field 完整代碼

自定義的Field 供參考:

CheckBoxField
FileField
EmailField (input類型為text通用)
Session   

設(shè)計思想: 利用Cookie 自定義一個Session來存儲每個用戶信息

實現(xiàn)思路: 1. Session信息設(shè)計成一個大字典,key對應(yīng)用戶唯一識別加密串,value對應(yīng)空字典{}存儲用戶信息,存放在服務(wù)端上。

      2. 為用戶請求生成一個唯一加密串,寫入到Cookie信息中,Session_id = 加密串,用于區(qū)分每一個用戶。

      3. 當用戶請求到來時,獲取該請求的Cookie信息,判斷是否存在Session_id(用戶唯一識別加密串)?

      => 如果存在Session_id 并且在 Session大字典中找到相同的 key,記錄Session_id

      => 其他情況下一律,生成加密串,寫入到Cookie中,同時寫入到 Session大字典中

復(fù)制代碼
class CacheSession():
    session_id = "__balabala__"     # Cookie中為Session存儲的名字
    session_container = {}        # Session大字典

    def __init__(self,handler):
        self.handler = handler
        client_random_str = self.handler.get_cookie(CacheSession.session_id,None)
        if client_random_str and client_random_str in CacheSession.session_container:
            self.random_str = client_random_str
        else:
            self.random_str = self.__container__random__str()
            CacheSession.session_container[self.random_str] = {}

        expires_time = time.time() + config.SESSION_EXPIRES
        self.handler.set_cookie(CacheSession.session_id, self.random_str, expires=expires_time)  # 方便后續(xù)定義過期時間!

    def __container__random__str(self):      # 生成加密串
        hash = hashlib.md5()
        hash.update(bytes(str(time.time()), encoding='utf-8'))
        random_str = hash.hexdigest()
        return random_str
復(fù)制代碼

利用方法:1. 當用戶請求到達每個Handler時,我們都需要先實例化一個CacheSession(),

     2. 此時我們可以定義一個父類BaseHandler,initialize() 方法中寫入要執(zhí)行代碼,

復(fù)制代碼
import tornado.web
form session import SessionFactory

class BaseHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.session = SessionFactory.get_session_obj(self)
復(fù)制代碼

可以看到,我們在session.py中定義了一個新的類SessionFactory,用來選擇合適的方法,初始化Session,

該類通過讀取配置文件config中的SESSION_TYPE選擇適合的Session類進行初始化,并且返回一個Session對象,該對象最終存儲在 self.session中。

復(fù)制代碼
class SessionFactory():

    @staticmethod
    def get_session_obj(handler):
        if config.SESSION_TYPE == 'cache':
            obj = CacheSession(handler)
        elif config.SESSION_TYPE == 'memcached':
            obj = MemcachedSession(handler)
        elif config.SESSION_TYPE == 'redis':
            obj = RedisSession(handler)
        return obj
復(fù)制代碼

Handler 中使用Session

class LoginUserHandler(BaseHandler):
    def post(self, *args, **kwargs):
        self.session['is_login'] = 1
        self.write('ok')

1.緩存Session

View Code

2.memcache session

View Code

3.radis session

View Code

需要注意的是:__setitem__,__getitem__和__delitem__  使用類似字典方式設(shè)置,訪問,刪除成員。

在緩存Session 中,他們的使用方法與字典差別不大。

在memcache 中,鍵值對key,value 都是以字符串的形式存儲的,

     在設(shè)置值前需要將value值通過json轉(zhuǎn)換成字典形式,再對字典進行操作,操作完畢后,用json轉(zhuǎn)換回字符串,存儲回原來位置!

在redis 中,選用hash操作進行存儲,如果待存儲的value值為字典,需要先把value通過json轉(zhuǎn)換成字符串,再存儲在redis中,

     獲取某個key的value值時,由于hash中value是以bytes存儲,需要先轉(zhuǎn)換成str類型,再判斷該key存儲的是字典,還是普通字符串

Session所有的完整代碼:

session.py
request_handle.py
config.py 配置文件
分頁

設(shè)計思路:與Tornado篇分頁同理

前端:

前端頁面

后臺Url配置:

1
(r"/index/(?P<page>\d*)", IndexHandler),

后臺Handle:

復(fù)制代碼
class IndexHandler(BaseHandler):
    def get(self, page):
        query = QueryContent()
        page_obj = pager.Pagiantion(page, all_item=query.queryCounts(), per_num=5)  #page 當前頁碼 , all_item 總數(shù)據(jù)條數(shù), per_num 每頁顯示條數(shù)
        str_page = page_obj.page_str('/index/')

        self.render("index.html", str_page=str_page )
復(fù)制代碼

Pagiantion 分頁類:

Pagiantion 分頁類
分頁標簽 Css

頁面登陸驗證(裝飾器方式實現(xiàn))

1.普通登陸驗證

1
2
3
4
5
6
7
8
9
10
LOGIN_URL = '/login'
def auth_login_redirect(func):
  
    def inner(self, *args, **kwargs):
        if not self.session['is_login']:
            self.redirect(config.LOGIN_URL)
            return
        func(self, *args, **kwargs)
    return inner

2.ajax提交數(shù)據(jù)的登陸驗證

1
2
3
4
5
6
7
8
9
10
def auth_login_json(func):
  
    def inner(self, *args, **kwargs):
        if not self.session['is_login']:
            rep = BaseResponse()
            rep.summary = "auth failed"
            self.write(json.dumps(rep.__dict__))
            return
        func(self, *args, **kwargs)
    return inner
文件上傳

為了美觀 , 文件上傳標簽一半由兩部分組成 file標簽和 button標簽

1
2
3
4
<div id="main" class="up-block">
    <input name="file" id="my_file" class="file-path" type="file" onchange="imagechange()"/>
    <input type="button" name="action" value="Upload" class="a-upload"/>
<div>

file標簽會設(shè)置 透明度 和 定位在button上 , 綁定onchange事件

復(fù)制代碼
.up-block{
    position: relative;
}
.file-path{
    position: absolute;
    width: ..px;
    height: ..px;
    font-size: ..px;
    opacity: 0;
        z-index: 10;
}
復(fù)制代碼

圖片上傳后,展示在上傳頁面:

方法一:利用iframe實現(xiàn)

View Code

抽屜網(wǎng)實現(xiàn),完整代碼:

jQ 代碼
Html 代碼
Css 代碼

方法二:ajax實現(xiàn)

通過Ajax的FormData對象來實現(xiàn)。詳情參考ajax篇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<input type="file" name="uploadimage" id="uploadimage">
var fileObj = $("#uploadimage")[0].files[0];
var form = new FormData();
form.append("uploadimage", fileObj);
$.ajax({
    url:'/uploadimg',
    type:'POST',
    data:form,
    processData: false,  // tell jQuery not to process the data
    contentType: false,
    success:function (data, statusText, xmlHttpRequest) {
        obj = JSON.parse(data);
    }
})

  

  

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多