flask 之url_for()

本文详细介绍了Flask框架中url_for函数的使用方法,包括如何为动态路由传参及在静态模板中的应用。通过具体示例展示了如何生成动态URL和获取静态资源的绝对路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

url_for(endpoint, **values):
用法
1.为动态路由传参
eg: <td><a target="_blank" href="{{ url_for("front.post_detail",post_id=post.id) }}">{{ post.title }}</a></td>
source:
    @bp.route('/p/<post_id>/')
    def post_detail(post_id):
        post = PostModel.query.get(post_id)
        if not post:
            abort(404)
        return render_template('front/front_pdetail.html',post=post)

2.在静态模板中使用
被flask当做特殊路由处理
      url_for('static',filename='css/styles.css',_external=True)
      得到的结果:http://localhost:5000/static/css/styles.css
      <link rel="stylesheet" href="{{ url_for('static',filename='assets/vendor/linearicons/style.css') }}">
      当_external为True时返回url绝对路径,否则返回相对路径

from flask import Flask, render_template, request, redirect, url_for, flash from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user from werkzeug.security import generate_password_hash, check_password_hash from datetime import datetime app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///shop.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = 'login' # 用户模型 class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) password_hash = db.Column(db.String(128)) orders = db.relationship('Order', backref='user', lazy=True) cart_items = db.relationship('CartItem', backref='user', lazy=True) def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) # 商品模型 class Product(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), nullable=False) description = db.Column(db.Text) price = db.Column(db.Float, nullable=False) stock = db.Column(db.Integer, nullable=False) image_url = db.Column(db.String(200)) # 订单模型 class Order(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) date_ordered = db.Column(db.DateTime, default=datetime.utcnow) status = db.Column(db.String(20), default='pending') # pending, completed, refunded items = db.relationship('OrderItem', backref='order', lazy=True) total_amount = db.Column(db.Float, nullable=False) def can_delete(self): """判断订单是否可以删除""" return self.status in ['pending', 'cancelled'] def can_deliver(self): """判断订单是否可以交付""" return self.status == 'pending' # 订单项模型 class OrderItem(db.Model): id = db.Column(db.Integer, primary_key=True) order_id = db.Column(db.Integer, db.ForeignKey('order.id'), nullable=False) product_id = db.Column(db.Integer, db.ForeignKey('product.id'), nullable=False) quantity = db.Column(db.Integer, nullable=False) price = db.Column(db.Float, nullable=False) product = db.relationship('Product') # 购物车项模型 class CartItem(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) product_id = db.Column(db.Integer, db.ForeignKey('product.id'), nullable=False) quantity = db.Column(db.Integer, nullable=False) product = db.relationship('Product') @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) # 首页 - 商品展示 @app.route('/') def index(): products = Product.query.all() return render_template('index.html', products=products) # 用户个人信息 @app.route('/profile') @login_required def profile(): return render_template('profile.html') # 购物车 @app.route('/cart') @login_required def cart(): cart_items = CartItem.query.filter_by(user_id=current_user.id).all() total = sum(item.product.price * item.quantity for item in cart_items) return render_template('cart.html', cart_items=cart_items, total=total) # 订单历史 @app.route('/orders') @login_required def orders(): user_orders = Order.query.filter_by(user_id=current_user.id).all() return render_template('orders.html', orders=user_orders) # 添加到购物车 @app.route('/add_to_cart/<int:product_id>', methods=['POST']) @login_required def add_to_cart(product_id): quantity = int(request.form.get('quantity', 1)) cart_item = CartItem.query.filter_by(user_id=current_user.id, product_id=product_id).first() if cart_item: cart_item.quantity += quantity else: cart_item = CartItem(user_id=current_user.id, product_id=product_id, quantity=quantity) db.session.add(cart_item) db.session.commit() flash('商品已添加到购物车!') return redirect(url_for('cart')) # 创建订单 @app.route('/create_order', methods=['POST']) @login_required def create_order(): cart_items = CartItem.query.filter_by(user_id=current_user.id).all() if not cart_items: flash('购物车为空!') return redirect(url_for('cart')) total_amount = sum(item.product.price * item.quantity for item in cart_items) order = Order(user_id=current_user.id, total_amount=total_amount) db.session.add(order) for cart_item in cart_items: order_item = OrderItem( order=order, product_id=cart_item.product_id, quantity=cart_item.quantity, price=cart_item.product.price ) db.session.add(order_item) # 更新库存 product = cart_item.product product.stock -= cart_item.quantity db.session.delete(cart_item) db.session.commit() flash('订单创建成功!') return redirect(url_for('orders')) # 申请退款 @app.route('/refund/<int:order_id>', methods=['POST']) @login_required def refund_order(order_id): order = Order.query.get_or_404(order_id) if order.user_id != current_user.id: flash('无权限操作此订单!') return redirect(url_for('orders')) if order.status == 'completed': order.status = 'refunded' # 恢复库存 for item in order.items: product = item.product product.stock += item.quantity db.session.commit() flash('退款申请已提交!') else: flash('订单状态不允许退款!') return redirect(url_for('orders')) # 用户认证相关路由 @app.route('/login', methods=['GET', 'POST']) def login(): if current_user.is_authenticated: return redirect(url_for('index')) if request.method == 'POST': username = request.form.get('username') password = request.form.get('password') remember = 'remember' in request.form user = User.query.filter_by(username=username).first() if user and user.check_password(password): login_user(user, remember=remember) next_page = request.args.get('next') return redirect(next_page or url_for('index')) flash('用户名或密码错误') return render_template('login.html') @app.route('/register', methods=['GET', 'POST']) def register(): if current_user.is_authenticated: return redirect(url_for('index')) if request.method == 'POST': username = request.form.get('username') email = request.form.get('email') password = request.form.get('password') confirm_password = request.form.get('confirm_password') if password != confirm_password: flash('两次输入的密码不一致') return redirect(url_for('register')) if User.query.filter_by(username=username).first(): flash('用户名已存在') return redirect(url_for('register')) if User.query.filter_by(email=email).first(): flash('邮箱已被注册') return redirect(url_for('register')) user = User(username=username, email=email) user.set_password(password) db.session.add(user) db.session.commit() flash('注册成功,请登录') return redirect(url_for('login')) return render_template('register.html') @app.route('/logout') @login_required def logout(): logout_user() return redirect(url_for('index')) @app.route('/update_profile', methods=['POST']) @login_required def update_profile(): email = request.form.get('email') if email != current_user.email: if User.query.filter_by(email=email).first(): flash('邮箱已被使用') else: current_user.email = email db.session.commit() flash('个人信息更新成功') return redirect(url_for('profile')) @app.route('/change_password', methods=['POST']) @login_required def change_password(): current_password = request.form.get('current_password') new_password = request.form.get('new_password') confirm_password = request.form.get('confirm_password') if not current_user.check_password(current_password): flash('当前密码错误') elif new_password != confirm_password: flash('两次输入的新密码不一致') else: current_user.set_password(new_password) db.session.commit() flash('密码修改成功') return redirect(url_for('profile')) # 购物车相关路由 @app.route('/update_cart_item/<int:item_id>', methods=['POST']) @login_required def update_cart_item(item_id): cart_item = CartItem.query.get_or_404(item_id) if cart_item.user_id != current_user.id: flash('无权限操作此购物车项') return redirect(url_for('cart')) quantity = int(request.form.get('quantity', 1)) if quantity > cart_item.product.stock: flash('商品库存不足') else: cart_item.quantity = quantity db.session.commit() flash('购物车更新成功') return redirect(url_for('cart')) @app.route('/remove_from_cart/<int:item_id>', methods=['POST']) @login_required def remove_from_cart(item_id): cart_item = CartItem.query.get_or_404(item_id) if cart_item.user_id != current_user.id: flash('无权限操作此购物车项') return redirect(url_for('cart')) db.session.delete(cart_item) db.session.commit() flash('商品已从购物车中移除') return redirect(url_for('cart')) # 添加删除订单功能 @app.route('/cancel_order/<int:order_id>', methods=['POST']) @login_required def cancel_order(order_id): order = Order.query.get_or_404(order_id) # 验证订单属于当前用户 if order.user_id != current_user.id: flash('无权限操作此订单', 'danger') return redirect(url_for('orders')) # 检查订单状态是否可以取消 if not order.can_delete(): flash('订单当前状态不可取消', 'danger') return redirect(url_for('orders')) try: # 恢复库存 for item in order.items: product = item.product product.stock += item.quantity # 更新订单状态为已取消 order.status = 'cancelled' db.session.commit() flash('订单已成功取消', 'success') except Exception as e: db.session.rollback() flash('取消订单时出错: {}'.format(str(e)), 'danger') return redirect(url_for('orders')) # 添加管理员端订单交付功能 @app.route('/admin/deliver_order/<int:order_id>', methods=['POST']) @login_required def deliver_order(order_id): # 检查是否是管理员 if not current_user.is_authenticated or current_user.username != 'admin': flash('需要管理员权限', 'danger') return redirect(url_for('index')) order = Order.query.get_or_404(order_id) # 检查订单状态是否可以交付 if not order.can_deliver(): flash('订单当前状态不可交付', 'danger') return redirect(url_for('admin_orders')) try: # 更新订单状态为已完成 order.status = 'completed' db.session.commit() flash('订单已标记为已交付', 'success') except Exception as e: db.session.rollback() flash('交付订单时出错: {}'.format(str(e)), 'danger') return redirect(url_for('admin_orders')) # 添加管理员端订单删除功能 @app.route('/admin/delete_order/<int:order_id>', methods=['POST']) @login_required def admin_delete_order(order_id): # 检查是否是管理员 if not current_user.is_authenticated or current_user.username != 'admin': flash('需要管理员权限', 'danger') return redirect(url_for('index')) order = Order.query.get_or_404(order_id) # 检查订单状态是否可以删除 if not order.can_delete(): flash('订单当前状态不可删除', 'danger') return redirect(url_for('admin_orders')) try: # 如果是待处理订单,需要恢复库存 if order.status == 'pending': for item in order.items: product = item.product product.stock += item.quantity # 删除订单项 for item in order.items: db.session.delete(item) # 删除订单 db.session.delete(order) db.session.commit() flash('订单已成功删除', 'success') except Exception as e: db.session.rollback() flash('删除订单时出错: {}'.format(str(e)), 'danger') return redirect(url_for('admin_orders')) # 添加管理员端页面管理路由 @app.route('/admin/orders')来自csdn里的哪个人 @login_required def admin_orders(): # 检查是否是管理员 if not current_user.is_authenticated or current_user.username != 'admin': flash('需要管理员权限', 'danger') return redirect(url_for('index')) # 获取所有订单,按日期降序排列 orders = Order.query.order_by(Order.date_ordered.desc()).all() return render_template('admin_orders.html', orders=orders) # 添加订单详情页面路由 @app.route('/order/<int:order_id>') @login_required def order_details(order_id): order = Order.query.get_or_404(order_id) # 检查是否是订单所有者或管理员 if order.user_id != current_user.id and current_user.username != 'admin': flash('无权限查看此订单', 'danger') return redirect(url_for('index')) return render_template('order_details.html', order=order) if __name__ == '__main__': with app.app_context(): db.create_all() app.run(debug=True)
05-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值