乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      【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ā)送過程: 頁面倒計時

      原理:設計計時器,每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
      表單驗證

      設計思想: 無論表單通過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名字一一對應;

           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)容

      復制代碼
      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__()
      復制代碼

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

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

        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 中

      復制代碼
      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
      復制代碼
      BaseForm 完整代碼

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

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

      復制代碼
      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__()
      復制代碼

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

      復制代碼
      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):
              ...
      復制代碼

          執(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   

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

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

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

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

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

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

      復制代碼
      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
      復制代碼

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

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

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

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

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

      復制代碼
      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
      復制代碼

      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__  使用類似字典方式設置,訪問,刪除成員。

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

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

           在設置值前需要將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 配置文件
      分頁

      設計思路:與Tornado篇分頁同理

      前端:

      前端頁面

      后臺Url配置:

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

      后臺Handle:

      復制代碼
      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 )
      復制代碼

      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標簽會設置 透明度 和 定位在button上 , 綁定onchange事件

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

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

      方法一:利用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)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多