一对一表关系html
Modulemysql
须要先建立对应的 Module ,这里采用以前创建好的 User 和 UserDetailsweb
from sqlalchemy.orm import relationship .... class User(Base): ..... class UserDetails(Base): ...... userdetail = relationship('User',backref='details',uselist=False,cascade='all') #SQLAlchemy里面用来表示表关系的,一对一 #relationship只在模型层面上生效,只在模型层面上 def __repr__(self): ........
自动添加属性sql
在刚才这里, User 里面原本是没有 details 这个属性的,可是在 UserDetails 里面添加 relationship 以后, User 实例会自动加上 details 属性数据库
relationshipsession
表关系是逻辑上的关系,可是 mysql 中并无直接说明表关系的东西,外键约束是一个表现形式,外键是一种表之间的约束,能够用来表示这种关系app
在SQLAlchemy里面,这个relationship表明了一对多的关系,固然咱们能够经过参数改变关系,它默认是一对多的关系,而这个关系是SQLAlchemy里面的,和数据库没有关系,可是relationship是和外键一块儿使用的。ssh
反向查询:tornado
row = session.query(User).get(4) print(row) print(row.details) #会把对应的详情表里面的对应的信息打印出来
结果为:oop
<User(id=4,username=小泼,password=55432,create_time=2019-04-01 23:10:56,_locked=False)>
[<UserDetails(id=2,id_card=543,last_login=2019-04-02 23:35:38,login_num=4,user_id=4)>]
正向查询:
row= session.query(UserDetails).get(2) print(row) print(row.userdetail)
结果为:
<UserDetails(id=2,id_card=543,last_login=2019-04-02 23:35:38,login_num=4,user_id=4)> <User(id=4,username=小泼,password=55432,create_time=2019-04-01 23:10:56,_locked=False)>
使用一对多
relationship 默认是 一对多 关系
uselist
uselist=True
默认是 True ,所以能够省略不写
多对多表关系
用户 和 文章之间,能够是一对多的关系,可是若是用户转载的话,就能够当作是 多对多 关系,那 多对多 关系在 SQLAlchemy 中怎么表示呢?
在Module中建立中间表
from sqlalchemy import Table user_article = Table('user_article', Base.metadata, Column('user_id', Integer, ForeignKey('user.id'), primary_key=True), #联合主键 Column('article_id', Integer, ForeignKey('article.id'), primary_key=True) )
在Module中建立 文章Module
class Article(Base): __tablename__ = 'article' id = Column(Integer,primary_key=True,autoincrement=True) content = Column(String(500),nullable=True) create_time = Column(DateTime,default=datetime.now) article_user = relationship('User',backref = 'article',secondary=user_article) def __repr__(self): return 'Article(id=%s, content=%s, creat_time=%s)' % ( self.id, self.content, self.create_time )
调用测试:
row = session.query(User).get(4) print(dir(row)) print(row) print(row.article) print(row.details) #会把对应的详情表里面的对应的信息打印出来
结果展现:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__mapper__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__table__', '__tablename__', '__weakref__', '_decl_class_registry', '_locked', '_sa_class_manager',
'_sa_instance_state', 'article', 'create_time', 'details', 'id', 'metadata', 'password', 'username'] <User(id=4,username=小泼,password=55432,create_time=2019-04-01 23:10:56,_locked=False)> [Article(id=1, content=litao进阶了, creat_time=2019-04-05 18:51:34), Article(id=2, content=式微走了, creat_time=2019-04-01 18:52:06)] [<UserDetails(id=2,id_card=543,last_login=2019-04-02 23:35:38,login_num=4,user_id=4)>]
包跟包管理
当把 Module 写好以后,该如何调用呢?
在模块中直接导入:
from data.user_modules import UserDetails
执行06-login.py,报错结果以下:
Traceback (most recent call last): File "/home/pyvip/tornado_pro/06-login.py", line 11, in <module> from data.user_modules import UserDetails File "/home/pyvip/tornado_pro/data/user_modules.py", line 2, in <module> from connect import Base ImportError: No module named 'connect'
解决方法:
简单登陆
定义06-login.py 文件
import sys import tornado.web import tornado.ioloop import tornado.httpserver import tornado.options from tornado.web import RequestHandler from tornado.options import define,options import util.ui_modules import util.ui_methods # import time from data.connect import session from data.user_modules import UserDetails, User define('port',default=8080,help='run server',type=int) # class MainHandler(RequestHandler): def get(self): self.write('请去login') class LoginHandler(RequestHandler): def get(self): self.render('in_out.html') def post(self): '''验证逻辑''' user = self.get_argument('name',None) password = self.get_argument('password',None) username = session.query(User).filter(User.username == user).first()print(username) if username and password == username.password: self.render('02-templates.html', username = username.username ) else: self.write('登陆失败') application = tornado.web.Application( handlers=[ (r'/',MainHandler), (r'/login',LoginHandler), ], debug=True, template_path = 'templates', static_path='static', # autoescape = None, #全局取消转义 ui_methods=util.ui_methods, ui_modules=util.ui_modules ) if __name__ == '__main__': tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port) tornado.ioloop.IOLoop.current().start()
渲染模板02-templates.html为
<!DOCTYPE html> {#去掉整个页面的转义#} {#{% autoescape None %}#} <html lang="en"> <head> <meta charset="UTF-8"> <title>Templates</title> </head> <body> {% if username !='' %} 欢迎 {{ username }} 登陆 <img src="static/images/01.jpg" width="200px" alt=""> <img src="{{ static_url('images/02.webp') }}" width="200px" alt=""> {% else %} 亲,请登陆 {% end %} </body> </html>
登陆成功返回以下内容:
登陆失败返回:
将LoginHandler的post方法的代码简化为get_name方法:
class LoginHandler(RequestHandler):
def get(self):
self.render('in_out.html')
def post(self):
'''验证逻辑'''
user = self.get_argument('name',None)
password = self.get_argument('password',None)
# username = session.query(User).filter(User.username == user).first()
username = User.get_name(user)
print(username)
if username and password == username.password:
self.render('02-templates.html',
username = username.username
)
else:
self.write('登陆失败')
在user_modules.py文件的User Module下定义get_name方法:
class User(Base): 。。。。 def __repr__(self): return ''' <User(id=%s,username=%s,password=%s,create_time=%s,_locked=%s)> '''%(self.id,self.username,self.password,self.create_time,self._locked) @classmethod def get_name(cls,user): '''用来查询用户名的方法''' return session.query(cls).filter(cls.username == user).first()