会员可以在此提问,百战程序员老师有问必答
对大家有帮助的问答会被标记为“推荐”
看完课程过来浏览一下别人提的问题,会帮你学得更全面
截止目前,同学们一共提了 128778个问题

from DBUtil import Base,Session
from sqlalchemy import Column,Integer,String,ForeignKey
from sqlalchemy.orm import relationship

class User(Base):
    __tablename__ = 't_connect_user'
    id = Column(Integer,primary_key = True, autoincrement = True)
    uname = Column(String(50)) 
    item = relationship('Item')

class Item(Base):
    __tablename__ = 't_connect_item'
    price = Column(Integer)
    uid = Column(Integer,ForeignKey("t_connect_user.id"))
    user = relationship('User',backref='item')

def create_table():
    User1 = User(uname = 'nihao')
    Item1 = Item(price = 40)
    User1.item = Item1
    with Session() as ses:
        ses.add(User1)
        # User1.item.append(Item1)
        ses.commit()

# class LoginUser(Base):
#   __tablename__ = 't_user_login'
#   id = Column(Integer,primary_key=True,autoincrement=True)
#   uname = Column(String(32),nullable=False)
#   passwd = Column(String(32),nullable=False)
#   user = relationship('User',uselist=False) # 不友好,总有警告


# class User(Base):
#   __tablename__ = 't_user_2'
#   id = Column(Integer,primary_key=True,autoincrement=True)
#   name = Column(String(32),nullable=False,name='name')
#   gender = Column(String(1))
#   address = Column(String(64))
#   login_id = Column(Integer,ForeignKey('t_user_login.id'))
#   login_user = relationship('LoginUser')

# def create_data():
#   login = LoginUser(uname = 'baizhan', passwd = '123')
#   user = User(name='百战',gender = '女',address ='北京')
#   # login.user = user # 建立关联关系

#   user.login_user = login

#   with Session() as ses:
#     ses.add(user)
#     ses.commit()

if __name__ == '__main__':
    Base.metadata.create_all()
    # create_table()

错误:

File "/Users/bytedance/python学习/SQLAlchemy/SQLAlchemy_env/lib/python3.11/site-packages/sqlalchemy/orm/mapper.py", line 693, in __init__

    self._configure_pks()

  File "/Users/bytedance/python学习/SQLAlchemy/SQLAlchemy_env/lib/python3.11/site-packages/sqlalchemy/orm/mapper.py", line 1400, in _configure_pks

    raise sa_exc.ArgumentError(

sqlalchemy.exc.ArgumentError: Mapper mapped class Item->t_connect_item could not assemble any primary key columns for mapped table 't_connect_item'



这个问题到底出自在哪呢?? 差了快一小时了也没找到

Python 全系列/第八阶段:Flask框架/Flask数据库 138楼

老师,我这个代码里,我在设置请求参数的时候,如果将uname里的required参数设置为True,就显示为用户名验证错误,如果设置为False,就会显示注册成功
from flask import Flask
from flask_restful import Resource,Api,inputs
from flask_restful.reqparse import RequestParser

app = Flask(__name__)

api = Api(app)

class RegisterView(Resource):
    def post(self):
        # 建立解析器
        parser = RequestParser()
        # 定义解析器规则
        parser.add_argument('uname',type=str,required=True,trim=True,help='用户名验证错误',location='args')
        parser.add_argument('pwd',type=str,default='123456',help='密码验证错误',location='args')
        parser.add_argument('age',type=int,help='年龄验证错误',location='args')
        parser.add_argument('gender',type=str,choices=['男','女','保密'],help='性别验证错误',location='args')
        parser.add_argument('birthday',type=inputs.date,help='生日验证错误',location='args')
        parser.add_argument('phone',type=inputs.regex('^1[356789]\d{9}$'),help='电话验证错误',location='args')
        parser.add_argument('homepage',type=inputs.url,help='个人主页验证错误',location='args')
        # 解析数据
        args = parser.parse_args()
        print(args)
        return {'msg':'注册成功!!'}


api.add_resource(RegisterView,'/register/')


if __name__ == '__main__':
    app.run(debug=True)

微信图片_20231010225843.png

Python 全系列/第八阶段:Flask框架/Flask高级 139楼

e40fba9592c478597cccbf2fc49f7b2.png

老师,创建数据库的时候报这个错误怎么解决

Python 全系列/第八阶段:Flask框架/Flask数据库 140楼
Python 全系列/第八阶段:Flask框架/Flask之Jinja2模版 141楼
Python 全系列/第八阶段:Flask框架/Flask之Jinja2模版 142楼

钩子函数好绕脑啊  还都是回调函数的用法

然后这些好抽象,好抽象啊   我盘了一天的逻辑 


老师您看我的理解 偏差大么?



flask 里面内置的信号

(相当于是对befor_request 和errorhandler等钩子函数 功能的补充)


1,before_render_template  模板渲染之前的信号  

    概念的理解:

相当于成vue 的DOM视图渲染之前  也就是 beforeMount(()=>{}) 的生命周期函数

    然后我们可以在这个信号的回调函数里面去实现相应的逻辑业务

    所以我在这个钩子函数中在写了一个简单的屏蔽非法字符的示例  


   



2,template_rendered     模板渲染之后的信号    

相当于vue的   DOM视图渲染完成之后  mounted 的生命周期函数

这玩意在vue中可以说太常用了 甚至达到了离不开他的地步,

但是由于我们flask不能直接操作DOM树 相比较用它去操作dom,干脆直接在js里去操作

但是我想到了 可以用它写了一个简单的监听 页面渲染完毕之后的性能示例  

之后的学习应该还能找到更多的用途把。



3,request_started     路由发送请求开始  在到达视图函数之前的信号  

# 约莫相当于vue中的前置路由守卫 ?  router.beforeEach((to, from, next)

这个里面我们应该可以填入一些 登录权限验证  但是感觉这个并不是常用的

因为它可以实现的业务  貌似我们用普通装饰器 或者在视图函数中都可以实现 




4,request_finished   请求结束时 在响应发送客户端之前的的时候

  那么我们在这个这个节点 获取用户的ip 然后统计到日志中 应该挺恰当的

毕竟请求已经结束了 我们写入日志 并不会影响请求的处理时间 




5,request_tearing_down  请求对象销毁的时候 发送的信号  相当于Vue的beforeDestroy 。都是在组件销毁之前发送的信号 

6,got_request_exception  请求过程中抛出异常时候 发送的信号  相当于vue中的errorCaptured  捕获错误

以上2个我们二选一  就是我们课堂说的可以捕获错误日志   这个是理解了



7,关于上下文对象还是朦朦胧胧的 感觉就挺神奇的 但是摸不着 所以它的信号触发节点 可以用来干嘛 还是不太清楚  我说理解的上下文对象 就是感觉是一个桥梁 可以传递数据  然后这个它里面的这个before_request 

每次发送请求的时候都会触发 这个感觉实用性好大!


滤的头昏脑胀的 越来越迷糊了





Python 全系列/第八阶段:Flask框架/Flask高级 146楼


这个是一个简单的捕获网页渲染完毕的耗时统计
 并且写入到了加入了日志  用于测试
'''


#引入我们的template_rendered这变量 待会儿用于监听信号
from flask import Flask,template_rendered,render_template,before_render_template,g
import time

app=Flask(__name__)

@app.route('/')   #定义一个首页路由
def index():
    return render_template('index.html')  #在这个路由里面 我放入了一些视频和图片 地址都是网络地址

@app.route('/home/')
def home():
    return render_template('home.html')  ##在这个路由里面 我放入了很多图片 地址也都是网络地址


#在页面渲染之前的钩子函数  记录开始的时间
def start_msg(sender,template,context):
    start_time = time.time()
    print(start_time,111111)
    #保存到我们的g变量中
    g.stime=start_time
before_render_template.connect(start_msg)    

#在页面渲染完毕的钩子函数  记录页面渲染完毕的时间  
# 拿到不同高度时间 然后写入日志 
def page_loading_log(sender,template,context):
    end_time = time.time()
    print(end_time,222222)
    print(f'{end_time-g.stime}',template,':这是页面渲染的时间')
    #当我们进入home的时候 这里打印的:
     #0.0010037422180175781<Template 'home.html'> :这是页面渲染的时间
     #当我们进入/这里打印的:
    #0.001003742218017578 <Template 'index.html'> :这是页面渲染的时间
    #由此可以拿到了进入不同页面 返回的不同的渲染时间 
    # 然后我们就可以写入log日志了 
template_rendered.connect(page_loading_log)
 
if __name__=='__main__':
    app.run(debug=True)

总结

#template_rendered 这个是视图渲染之后 发送的信号 
#我的理解是相当于 vue中的 mounted生命周期函数  DOM视图渲染完毕之后
#这个在vue中最常用。可以说是最核心的生命周期函数 在学习vue项目的时候
 这玩意天天用 几乎达到了离不开它的地步
 
'''
因为 DOM树 也就是元素标签 必须在视图渲染之后我们才能拿到
所以我们这个函数里面使用的逻辑 通常都是对DOM树的操作 
而flask并不能直接操作DOM树  相对比用vue操作dom树 或者js直接操作
 更加的便捷


我想了半天 这玩意在flask中可以干嘛?
终于让我想到了:
可以帮我们检测性能?比如网页渲染完毕的耗时?

之后的学习 应该还能找到这个钩子函数更多的用途把

Python 全系列/第八阶段:Flask框架/Flask高级 147楼


# before_render_template的应用 
#示例业务  加载视图之前  我们对数据过滤  屏蔽一些非法字符 的示例

#引用before_render_template  我们待会儿要用这个变量!来监听我们的逻辑函数   也就是在视图渲染之前把数据完成过滤
from flask import Flask,render_template,before_render_template,g

app=Flask(__name__)

#正常访问首页 
@app.route('/')
def index():
    # data()   #这里注册的data函数 是同样的功能  
    return render_template('index.html')

def filer_msg(sender,template,context): #过滤信息函数    #曹操 中操非法! 把操换成*
# def data():
    #比如我们获取数据 加入到了g中    这里简单拿一个字符串测试 
    g.msg='曹操不啰嗦,一心要拿荆州!'
    #这里课堂老师说 他会自动调用 before_render_template.send()  方法 
    #所以不需要我们去写了
    msg=g.get('msg')  
    if msg:
        g.msg = msg.replace('操', '*')  # 把操这个字符换成* 曹操非法了!  不准拿荆州!

# before_render_template.connect(filer_msg)  #执行信号监听   回调函数 在视图渲染前执行我们的逻辑!

@app.route('/home/')
def home():
    # data()
    return render_template('home.html')
#得到结果 是在home函数视图里面 曹操也被过滤了 



if __name__=='__main__':
    app.run(debug=True)


'''
html中调用
<body>
    <p>{{ g.msg }}</p>    
</body>
显示结果:  曹*不啰嗦,一心要拿荆州!  

#吐槽 可怜的曹操  名字都非法
'''


#总结 其实我们的数据过滤方法 放在任意一个函数里面 比如我们注释的上面的data() 
#但是每次视图渲染之前 都要调用data()这个函数 太麻烦了 
# 所以选择用flask给我们提供的 视图渲染之前的钩子信号! 
 一次性帮我们解决了所有视图渲染之前的数据过滤
 
 
我的理解是 before_render_template这个钩子 
视图渲染之前  相当于是vue中的DOM加载之前的生命周期函数beforMount
所以用法也往这个上面靠。






Python 全系列/第八阶段:Flask框架/Flask高级 148楼

百战程序员微信公众号

百战程序员微信小程序

©2014-2024 百战汇智(北京)科技有限公司 All Rights Reserved 北京亦庄经济开发区科创十四街 赛蒂国际工业园
网站维护:百战汇智(北京)科技有限公司
京公网安备 11011402011233号    京ICP备18060230号-3    营业执照    经营许可证:京B2-20212637