Tornado實現簡單登錄注冊


1.包的路徑問題

之前我們在基礎講過怎樣導入模塊和包,一般我們有兩種方式:

同路徑下直接:`import`或者`from packge import module`

如果是不同路徑下,需要添加路徑:

import sys
sys.path.append('/moudule_path')

除此之外,我們還可以使用相對路徑來導入,導入方式就是在包或者模塊前面加上一個或者兩個點`.`來表示相對路徑,其中一個點`.`表示同一個目錄,兩個`..`表示上一層目錄,這個表示方法和Linux的路徑表示是一樣的。

但是一旦在模塊中使用了點來導入其他的模塊,那么這個模塊就是包中的一個模塊,也就是說,這個模塊所在的文件加,可以作為一個包來管理。

包中的特殊文件`__init__.py`這是python的中一個比較特殊的文件,包的每一層目錄都需要這個文件,這個里面的對象屬性和方法,就是這個包的對象屬性和方法,如:

import xml
dir(xml)  #這其中的__all__屬性,就是定義在 __init__.py 中的

同時,想通過點`.`來不斷得到包中的包或者模塊,這個文件也是必不可少的,如:

from xml.dom import domreg

其次,當模塊中如果出現了以點`.`來導入的模塊,當你寫上`if __name__=='__main__'`的時候,再去執行的時候,會報錯,在python2中應該是這樣的報錯信息:

ValueError: Attempted relative import in non-package

在python3中大概是這樣的:

SystemError: Parent module '' not loaded, cannot perform relative import

這就告訴你,這個模塊是包中的一個模塊,但是你嘗試以腳本模式執行,但是這種模式不支持相對導入。如果你需要運行,你就需要去點,換成使用`sys`來添加路徑,如:

import sys
sys.path.append('../')
#添加路徑之后再導入模塊
import yourmodules

最后還有一種選擇導入,使用`try ...  except ...`來導入,如:

try:
  import moduleA
except:
  import moduleB


在項目中由於文件過多,肯定會使用包管理來管理我們的各個模塊。所以包管理是必須要知道的要點。

在一般情況下,我們會把常用的放在最頂層的目錄,或者頂層的配置文件中導入各個包或者模塊。

使用包管理的原因就是方便管理,所以我們的每個包里面是類似的相同的東西,不要隨便亂放。

2.MySQL的連接問題

MySQL的遠程連接要注意一下幾點:

2.1.首先是MySQL允許怎樣的登錄,是只能本地登錄還是允許遠程連接,這個在MySQL的配置文件中配置好的,打開`my.cnf`,如果是使用Ubuntu,那么是`/etc/mysql/mysql.conf.d`下的`mysqld.cnf`,找到`bind-address`,如果是`127.0.0.1`則代表只能本地連接,這個本地連接的意思是,先登錄上Linux,然后再執行`mysql -u username -p`

這種方式登錄,改成`0.0.0.0`就允許任何IP連接了,如果改成指定的IP,那么就只有指定的IP才能登錄。

2.2.看用戶是否允許遠程連接。`root`用戶權限太大,肯定只能允許本地連接,所以我們才新建了`admin`用戶,還有`develop`用戶,賦予不同的權限,同時允許這些用戶遠程連接。

 3.登錄和注冊

首先是路由等代碼如下:

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from tornado.options import define,options

import util.uimodules
import util.uimethod

from data.user_modules import User,session

define('port',default=8000,help='run port',type=int)

class AuthError(Exception):
    def __init__(self,msg):
        super(AuthError,self).__init__(msg)

class IndexHandler(tornado.web.RequestHandler):   
    def get(self):
        username = 'no'
        self.render('08sqlalchemy.html',username=username)

class LoginHandler(tornado.web.RequestHandler):    #登錄
    def get(self):
        self.render('08login.html',error=None)
    def post(self):
        username = User.by_name(self.get_argument('name',''))
        passwd = self.get_argument('password','')
        if username and username[0].password == passwd:
            self.render('08sqlalchemy.html',
                        username=username[0].username
                        )
        else:
            self.render('08login.html',error='登陸失敗')

class RegisterHandler(tornado.web.RequestHandler):   #注冊
    def get(self):
        self.render('08register.html',error=None)

    def post(self):
        if self._check_argument():
            try:
                self._create_user()
                self.render('08login.html',error=None)
            except AuthError as e:
                self.render('08register.html',error=e)
            except Exception as e:
                self.render('08register.html',error=e)
        else:
            self.render('08register.html',error='input error')

    def _check_argument(self):      #對密碼和用戶名進行檢驗
        username = self.get_argument('name','')
        passwd = self.get_argument('password1','')
        if len(username)<10 and len(passwd)<10:
            return True
        else:
            return False

    def _create_user(self):
        if User.by_name(self.get_argument('name','')):
            raise AuthError('Name is registered')
        if self.get_argument('password1','') != self.get_argument('password2',''):
            raise AuthError('Password error')
        user = User()
        user.username = self.get_argument('name','')
        user.password = self.get_argument('password1','')
        session.add(user)
        session.commit()


if __name__ == '__main__':
    tornado.options.parse_command_line()

    app = tornado.web.Application(
        handlers=[
            (r'/',IndexHandler),
            (r'/login',LoginHandler),
            (r'/register',RegisterHandler),
        ],
        template_path='templates',
        static_path='static',
        ui_methods=util.uimethod,
        ui_modules=util.uimodules,
        debug=True,
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

主頁頁面的HTML

{% extends "./base.html" %}

{% block title %} {{ username }} {% end %}


{% block body %}

    {% if username!='no' %}
        歡迎用戶 {{ username }} 登錄
        <br>
        <img src="/static/images/c.jpg" width="250" height="250">
        <br>
    {% else %}
        {% include "./06include.html" %}
        <br>
        <img src="/static/images/b.jpg" width="250" height="250">
        <br>
    {% end %}

{% end %}

登錄的HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
{% if error %}
    {{ error }}
{% end %}

<form method="post" action="/login">
    <p>用戶名<br><input type="text" name="name"></p>
    <p>密碼<br><input type="text" name="password"></p>
    <input type="submit">
</form>

</body>
</html>

注冊的HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
</head>
<body>

<h1>Register</h1>
{% if error %}
    {{ error }}
{% end %}

<form method="post" action="/register">
    <p>用戶名<br><input type="text" name="name"></p>
    <p>密碼<br><input type="text" name="password1"></p>
    <p>再次輸入密碼<br><input type="text" name="password2"></p>
    <input type="submit">
</form>
  
</body>
</html>

 


免責聲明!

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



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