1. 程式人生 > >4 資料庫和使用者資訊

4 資料庫和使用者資訊

資料庫和使用者中心

資料庫

users 表

posts 表

使用者註冊 和登陸

儲存到 user 表

增加 models

models/account.py

class Users(Base):
	__tablename__ = 'users'

	id = Column(Integer, primary_key=True, autoincrement=True)
	name = Column(String(50), unique=True, nullable=False)
	password = Column(String(50), nullable=False
) created = Column(DateTime, default=datetime.now) email = Column(String(50)) last_login = Column(DateTime) def __repr__(self): return '<User(#{}:{})>'.format(self.id, self.name) # 判斷使用者是否存在於資料庫中 @classmethod def is_exists(cls, username): return session.query(exists().where(Users.name ==
username)).scalar() # 增加使用者到資料庫中 @classmethod def add_user(cls, username, password, email=''): user = Users(name=username, password=password, email=email, last_login=datetime.now()) session.add(user) session.commit() # 查詢使用者username對應的密碼 @classmethod def get_passwd(cls, username): user =
session.query(Users).filter_by(name=username).first() # 如果使用者存在 返回密碼 if user: return user.password # 使用者不存在 返回空 else: return ''

增加 utils 輔助函式

utils/account.py


def hashed(passwd):
	return hashlib.md5(passwd.encode('utf8')).hexdigest()


def authenticate(username, password):
	"""
	登入認證
	:param username:
	:param password:
	:return:
	"""
	if username and password:
		# 獲取資料庫中username對應的密碼
		user_passwd = Users.get_passwd(username)
		# 如果使用者存在 密碼匹配
		if user_passwd and user_passwd == hashed(password):
			return True
	return False


def save_last_login(username):
	"""
	# 儲存使用者username最後登入時間
	:param username:
	:return:
	"""
	t = datetime.now()
	print("user {} login at {}".format(username, t))
	session.query(Users).filter_by(name=username).update({Users.last_login: t})
	session.commit()


def register(username, password, email):
	"""
	註冊
	:param username:
	:param password:
	:param email:
	:return:
	"""
	# 檢視使用者是否存在於資料庫中
	if Users.is_exists(username):
		return {'msg': '使用者已存在'}
	hash_passwd = hashed(password)
	# 新增使用者到資料庫
	Users.add_user(username, hash_passwd, email)
	return {'msg': 'ok'}

完成註冊 /signup

auth.py



class SignupHandler(AuthBaseHandler):
	"""
	註冊
	"""

	def get(self, *args, **kwargs):
		self.render('signup.html', msg='')

	def post(self, *args, **kwargs):
		username = self.get_argument('username', 'no')
		email = self.get_argument('email', 'no')
		password1 = self.get_argument('password1', 'no')
		password2 = self.get_argument('password2', 'no')

		if username and password1 and password2:
			if password1 != password2:
				self.render('signup.html', msg='兩次輸入的密碼不一致')
			else:
				ret = register(username, password2, email)  # 註冊函式
				# 註冊成功
				if ret['msg'] == 'ok':
					self.session.set('tudo_user_info', username)  # 註冊成功後直接設定session(自動登入)
					self.redirect('/')  # 註冊成功後自動訪問首頁
				else:
					self.render('signup.html', msg=ret['msg'])
		else:
			self.render('signup.html', msg={'sign failed'})

            

更新 /login


class LoginHandler(AuthBaseHandler):
	"""
	登入
	"""

	def get(self, *args, **kwargs):
		if self.current_user:  # 如果已經登入 訪問/login自動跳轉到/
			self.redirect('/')
		next = self.get_argument('next', '/')  # 注意是/  沒有next (從logout跳轉過來)就跳轉到首頁
		self.render('login.html', nextname=next, error=None)

	def post(self, *args, **kwargs):
		username = self.get_argument('username')
		password = self.get_argument('password')
		next = self.get_argument('next', '/')
		passed = authenticate(username, password)  # 登入認證

		if passed:
			self.session.set('tudo_user_info', username)
			# 儲存最後登入時間
			save_last_login(username)
			self.redirect(next)
		else:
			self.render('login.html', nextname=next, error='使用者名稱或密碼錯誤')


.scalar()

如果查詢到很多結果,丟擲異常。
如果只有一個結果,返回它,

如果沒有結果,返回None

圖片

儲存到 post 表

增加 models

models/account.py

class Posts(Base):
	__tablename__ = 'posts'
	id = Column(Integer, primary_key=True, autoincrement=True)
	image_url = Column(String(50))
	thumb_url = Column(String(50))
	user_id = Column(Integer, ForeignKey('users.id'))
	# Post 有user屬性 存放Users物件 , Users有posts屬性 存放Posts物件(多對一)
   user = relationship('Users', backref='posts', uselist=False, cascade='all')

class Posts(Base):
   """
   使用者圖片資訊
   """
   __tablename__ = 'posts'
   id = Column(Integer, primary_key=True, autoincrement=True)
   image_url = Column(String(50))  # 大圖路徑
   thumb_url = Column(String(50))  # 縮圖路徑
   user_id = Column(Integer, ForeignKey('users.id'))
   # Post 有user屬性 存放Users物件 , Users有posts屬性 存放Posts物件
   user = relationship('Users', backref='posts', cascade='all')

  # 儲存使用者上傳的圖片資訊  圖片和特定的使用者建立關係(這張圖片是由這個使用者傳上來的)
	@classmethod
	def add_post_for(cls, username, image_url, thumb_url):
		user = session.query(Users).filter_by(name=username).first()
		post = Posts(image_url=image_url, thumb_url=thumb_url, user=user)
		session.add(post)
		session.commit()
alembic revision --autogenerate -m 'add table for posts'

alembic upgrade head

增加 utils 輔助函式

utils/account.py



def get_post_for(username):
	"""
	獲取使用者上傳的圖片資訊
	:param username:
	:return:
	"""
	user = session.query(Users).filter_by(name=username).first()
	if user:
		return user.posts
	else:
		return []


def get_post(post_id):
	"""
	獲取使用者的特定圖片
	:param post_id:
	:return:
	"""
	post = session.query(Posts).filter_by(id=post_id).first()
	return post

更新 /upload 和輔助函式

main.py


class UploadHandler(AuthBaseHandler):
	"""
		接受圖片上傳
		"""

	@tornado.web.authenticated
	def get(self, *args, **kwargs):
		self.render('upload.html')

	def post(self, *args, **kwargs):
		# 提取表單中‘name’為‘newimg’的檔案元資料   獲取上傳檔案資訊
		img_files = self.request.files.get('newimg')

		if img_files:
			for img in img_files:
				# img_file['filename']獲取檔案的名稱  有些檔案需要以二進位制的形式儲存
				image_url = 'uploads/{}'.format(img['filename'])
				# ./ static / uploads / thumbs / 701728.jpg
				save_to = './static/{}'.format(image_url)
				with open(save_to, 'wb') as f:
					f.write(img['body'])  # img_file['body']獲取檔案的內容

				# 生成縮圖  ./ static / uploads /thumbs/ 701728_200x200.jpg
				save_thumb_to = photo.make_thumbs(save_to)
				thumb_url = os.path.relpath(save_thumb_to, 'static')

				# 儲存圖片的地址 把url存到資料庫
				Posts.add_post_for(self.current_user, image_url, thumb_url)

			self.write({'msg': 'got file: {}'.format(img_files[0]['filename'])})

		else:
			self.write({'msg': 'empty form data'})

更新 /index 和 /explore

main.py


class IndexHandler(AuthBaseHandler):
	"""
	首頁
	"""

	@tornado.web.authenticated
	def get(self, *args, **kwargs):
		post_list = get_post_for(self.current_user)
		self.render('index.html', post_list=post_list)


class ExploreHandler(AuthBaseHandler):
	"""
	發現頁
	"""

	@tornado.web.authenticated
	def get(self, *args, **kwargs):
		post_list = get_post_for(self.current_user)
		self.render('explore.html', post_list=post_list)


class PostHandler(AuthBaseHandler):
	"""
	詳情頁
	"""

	@tornado.web.authenticated
	def get(self, post_id):
		post = get_post(post_id)
		if not post:
			self.write('post id is not exists')
		else:
			self.render('post.html', post=post)


index.html

{% extends 'base.html' %}

{% block title %}
    index page
{% end %}

{% block content %}
    <p><a href="/logout">登出</a></p>
    {% for post in post_list %}
        <img src="{{ static_url(post.image_url) }}" width="666">
    {% end %}

{% end %}



explore.html

{% extends 'base.html' %}

{% block title %}
    explore page
{% end %}

{% block content %}
      <p><a href="/logout">登出</a></p>
     {% for post in post_list %}
        <img src="{{ static_url(post.image_url) }}" width="200px">
    {% end %}
{% end %}

post.html

{% extends 'base.html' %}

{% block title %}
    post page
{% end %}

{% block content %}
    <img src="{{ static_url(post.image_url)}}" width="560px">
{% end %}

photo.py

# 生成縮圖
def make_thumb(path):
   print(path)  # ./static/uploads/1172020.jpg

   # basename:擷取path中的去目錄部分的最後的檔案或路徑名
   # dirname:擷取path中的目錄路徑

   dirname = os.path.dirname(path)  # static/uploads
   file, ext = os.path.splitext(os.path.basename(path))  # file=1172020   ext=.jpg

   im = Image.open(path)  # 開啟./static/uploads/1172020.jpg圖片

   size = (200, 200)
   im.thumbnail(size)  # 按長200高200縮放
   # *size = 200,200 解包
   save_thumb_to = os.path.join(dirname, 'thumbs', '{}_{}x{}.jpg'.format(file, *size))

   # 儲存./static/uploads/thumbs/1172020_200x200.jpg
   im.save(save_thumb_to, "JPEG")

   return save_thumb_to

作業

把資料儲存用起來。(提交簡單截圖就可以了)

完整程式碼

app.py

import tornado.web
import tornado.options
import tornado.ioloop
from tornado.options import define, options

from handlers import main,auth

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


class Application(tornado.web.Application):
	def __init__(self):
		handlers = [
			(r'/', main.IndexHandler),
			(r'/explore', main.ExploreHandler),
			(r'/post/(?P<post_id>[0-9]+)', main.PostHandler),
			(r'/upload', main.UploadHandler),
			(r'/login', auth.LoginHandler),
			(r'/logout', auth.LogoutHandler),
			(r'/signup', auth.SignupHandler),
		]
		settings = dict(
			debug=True,
			template_path='templates',
			static_path='static',
			login_url='/login',
			cookie_secret='bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=',
			pycket={
				'engine': 'redis',
				'storage': {
					'host': 'localhost',
					'port': 6379,
					# 'password': '',
					'db_sessions': 5,  # redis db index
					'db_notifications': 11,
					'max_connections': 2 ** 30,
				},
				'cookies': {
					'expires_days': 30,
				},
			}
		)

		super(Application, self).__init__(handlers, **settings)


application = Application()

if __name__ == '__main__':
	tornado.options.parse_command_line()
	application.listen(options.port)
	print("Server start on port {}".format(str(options.port)))
	tornado.ioloop.IOLoop.current().start()

main.py

import tornado.web
from utils import photo
from models.account import Posts
from pycket.session import SessionMixin
from utils.account import get_post_for,get_post
import os


class AuthBaseHandler(tornado.web.RequestHandler, SessionMixin):
	def get_current_user(self):
		return self.session.get('tudo_user_info')


class IndexHandler(AuthBaseHandler):
	"""
	首頁
	"""

	@tornado.web.authenticated
	def get(self, *args, **kwargs):
		post_list = get_post_for(self.current_user)
		self.render('index.html', post_list=post_list)


class ExploreHandler(AuthBaseHandler):
	"""
	發現頁
	"""

	@tornado.web.authenticated
	def get(self, *args, **kwargs):
		post_list = get_post_for(self.current_user)
		self.render('explore.html', post_list=post_list)


class PostHandler(AuthBaseHandler):
	"""
	詳情頁
	"""

	@tornado.web.authenticated
	def get(self, post_id):
		post = get_post(post_id)
		if not post:
			self.write('post id is not exists')
		else:
			self.render('post.html', post=post)


class UploadHandler(AuthBaseHandler):
	"""
		接受圖片上傳
		"""

	@tornado.web.authenticated
	def get(self, *args, **kwargs):
		self.render
            
           

相關推薦

4 資料庫使用者資訊

資料庫和使用者中心 資料庫 users 表 posts 表 使用者註冊 和登陸 儲存到 user 表 增加 models models/account.py class Users(Base): __tablename__ = 'users' id =

1.4 資料庫常用SQL語句(正文)——MySQL資料庫命令SQL語句

前面我們已經講述了,登入時,我們使用mysql –u root –p命令進行,此時如果設定了密碼,則需要輸入密碼。 輸入密碼後即進入MySQL的操作介面,此時,命令列窗體左側顯示“mysql>”表示此時可接受mysql命令。 (1)列出全部資料庫命令 我們使用“show databases;”命令列

SQL Server資料庫開發(4.索引檢視)

一、索引 定義:是資料表中資料和相應儲存位置的列表。 作用:可以提高在表或檢視中查詢資料的速度。 1.分類:聚集索引,非聚集索引 聚集索引:指表中資料行的物理儲存順序與索引順序完全相同。 非聚集索引:不該表表中資料行的物理儲存位置,資料與索引分開儲存,通過索引指向的地址與表中的資

zabbix3.4資料庫遷移,將serverdatabase分到不同的兩臺server

zabbix目前已經是很多公司採用的比較常見的一種系統監控工具,單從個人經驗來講,安裝zabbix應該將資料庫和zabbix-server分開安裝到不同兩臺機器,然後通過網路(最好是內網)連線訪問資料庫是一種比較好的方式。 將資料庫和zabbix-server分開安裝的好處

mongodb檢視資料庫表的資訊

mongodb檢視資料庫和表的方法比較簡單,在為這裡推薦使用stats的方法,直觀並且詳細。 1、檢視資料庫 db.stats(); 輸出: { "db" : "sirius", "collections" : 3,

單點登入 CAS 5.* - 從資料庫獲取使用者資訊 - 4

前面演示的專案 都是使用的固定使用者,現在,可以嘗試從資料庫獲取使用者+密碼嘗試登入, 建立表和資料: CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL,

javaWeb實戰教程4-jdbc連線資料庫junit單元測試

javaWeb實戰教程 2.5 junit單元測試 我們在平時做程式碼時,每完成一個方法都需要先測試再提交,在java中比較常用的一個測試方法就是使用junit。 首先在專案中加入junit的jar包:junit-4.7.jar;將jar包複製到W

如何做到在虛擬資料庫真實資料庫之間自由切換?【低調贈送:QQ高仿版GG 4.4 最新原始碼】

      記得以前在公司上班時,有時候白天的活沒幹完,我就會把工作帶回家晚上加班繼續做。但是,我們開發用的資料庫是部署在公司局網內部的一臺伺服器上的,在家裡是肯定連不上這臺機器的。在家裡沒有資料庫,服務端就跑不起來,功能也就沒辦法除錯。後來我們的解決方法就是使用虛擬資料庫。在公司上班時,就使用公司局網的真實

Oracle 資料庫補丁下載地址 12.1.0.2 11.2.0.4 11.2.0.1

Oracle 資料庫軟體和補丁下載地址 12.1.0.2 11.2.0.4 11.2.0.1  AIX Linux Windows平臺 Oracle 資料庫軟體和補丁下載地址、百度雲盤共享  12.1.0.2 11.2.0.4 11.2.0.1  AIX Linux W

如何通過ADO獲得Access資料庫中的所有使用者表資訊

本文介紹一種通過ADO列舉Access檔案中所用使用者表和表資訊的方法,僅供參考,原始碼在VC6.0 +XP環境通過測試。 首先,需要引入msado15.dll檔案,在stdafx.h中新增: #import "c:/program files/common files/s

如何通過SpringMyBatis的整合實現資料庫表中資訊查詢?

UserMapper.javapackage cn.kgc.dao; import java.util.List; import cn.kgc.pojo.User; public interface UserMapper { //根據條件(使用者名稱稱、角色

Mac 下解決虛擬機virtualbox 4.3windows共享問題

jsb windows安裝 mman 重新啟動 con 安裝ad clas 啟動 sdn mac上面安裝了最新的virtualbox,有些軟件還是須要windows的。 1,在設置了共享之後,仍然不能使用 不能共享 2,找了半天發現須要windows安裝 VB

《挑戰程序競賽》 2.1.4 部分問題

als 按順序 space code log pre std mes namespace 題意:給定整數a1,a2,a3,...,an,判斷是否可以從中選出若幹數,使它們的和恰好為k。 解法:利用dfs深度優先遍歷,從a1開始按順序決定每個數是加還是不加。 code

【雜題集】【51NOD 1267】4個數為0

www namespace quest color https question clas amp -a 4個數和為0 鏈接: 原題 題意: ... 這 思路: 由於(n=1000),O(n^2)的算法也可一試。

4.tp5url路由

str 分享 ont 參數 .cn images strong bsp -s 生成的url,自動加上html,偽靜態後綴。 總結: 1.參數綁定 2.訪問路徑大小寫 3.定義路由 4.設置url分隔符 5.路由變量規則 6.生成url地址 4.tp5

玩轉樹莓派——升級NOOBS離線安裝介質到Raspbian 4.9Windows 10 IoT C

note log 基本 方法 打開 通過 gawk adc zip解壓 為樹莓派做系統升級是我一直想做的事。時間總是覺得不夠,於是也好久沒有碰。 直到前幾天MVP群裏有兄弟問大家的github來互相關註,我才突然想起之前寫過的制作離線安裝介質的文章:http://haoh

【python】(第一章)1.4 數字表達式

python以下內容是我學習《Python基礎教程》第2版 這本書所寫的筆記 轉載請註明出處1.>>> 2.75%.50.25【不同】C語言中取余運算必須為整數,不能是浮點型2.>>>(-3)**29【不同】C語言中pow (double x,double n);(將返回

微軟URLRewriter.dll的url重寫在目標框架.Net Framework2.0、4.0應用程序池經典模式、集成模式下的配置

原理 有一個 write 地址 ack 解決 targe 應用程序池 url重寫 大家參考幾篇園子裏面的這篇文章: 文章1:微軟URLRewriter.dll的url重寫的簡單使用 (講解了使用UrlReWriter.dll的下載、web.config如何在目標框架2.

qt-4.8.4安裝環境變量配置

eight pat too dir ack console int separate fonts 在Linux中分別安裝應用於不同平臺的Qt:PC。嵌入式X86;ARM。 這三者PC版、嵌入式X86版和ARM版的差別主要體如今:當configure時分別加了不同的

基於laravel5.4 vue vue-element搭建的單頁面後臺CMS

data pos dev https art .sql blog -s sql 介紹 該項目後臺是基於vue和laravel搭建的單頁面CMS系統,包含了文章管理,權限管理,用戶管理等基本模塊。 前臺使用了傳統web技術,laravel渲染搭建了個博客系統 githu