150 lines
4.7 KiB
Python
150 lines
4.7 KiB
Python
from flask import Blueprint, render_template, request
|
|
from flask_login import login_required, current_user
|
|
from models import Product, Category, SizeEnum, db
|
|
from sqlalchemy import or_, and_
|
|
from extensions import db
|
|
|
|
main_bp = Blueprint('main', __name__)
|
|
|
|
@main_bp.route('/')
|
|
def home():
|
|
featured_products = Product.query.order_by(Product.id.desc()).limit(8).all()
|
|
|
|
|
|
best_sellers = Product.query.order_by(
|
|
Product.stock.desc(),
|
|
Product.price.desc()
|
|
).limit(4).all()
|
|
|
|
categories = Category.query.all()
|
|
|
|
return render_template('home.html',
|
|
featured_products=featured_products,
|
|
best_sellers=best_sellers,
|
|
categories=categories)
|
|
|
|
@main_bp.route('/products')
|
|
def products():
|
|
search_query = request.args.get('q', '').strip()
|
|
category_id = request.args.get('category', '')
|
|
size = request.args.get('size', '')
|
|
color = request.args.get('color', '')
|
|
material = request.args.get('material', '')
|
|
company = request.args.get('company', '')
|
|
min_price = request.args.get('min_price', '')
|
|
max_price = request.args.get('max_price', '')
|
|
in_stock_only = request.args.get('in_stock') == '1'
|
|
sort_by = request.args.get('sort', 'newest')
|
|
|
|
query = Product.query
|
|
|
|
if search_query:
|
|
search_term = f"%{search_query}%"
|
|
query = query.filter(
|
|
or_(
|
|
Product.name.ilike(search_term),
|
|
Product.description.ilike(search_term),
|
|
Product.color.ilike(search_term),
|
|
Product.material.ilike(search_term),
|
|
Product.company.ilike(search_term),
|
|
Product.category.has(Category.name.ilike(search_term))
|
|
)
|
|
)
|
|
|
|
if category_id:
|
|
try:
|
|
query = query.filter(Product.category_id == int(category_id))
|
|
selected_category_name = Category.query.get(int(category_id)).name
|
|
except (ValueError, TypeError):
|
|
selected_category_name = None
|
|
else:
|
|
selected_category_name = None
|
|
|
|
if size:
|
|
query = query.filter(Product.size == size)
|
|
|
|
if color:
|
|
query = query.filter(Product.color.ilike(f"%{color}%"))
|
|
|
|
if material:
|
|
query = query.filter(Product.material.ilike(f"%{material}%"))
|
|
|
|
if company:
|
|
query = query.filter(Product.company.ilike(f"%{company}%"))
|
|
|
|
if min_price:
|
|
try:
|
|
query = query.filter(Product.price >= float(min_price))
|
|
except ValueError:
|
|
pass
|
|
|
|
if max_price:
|
|
try:
|
|
query = query.filter(Product.price <= float(max_price))
|
|
except ValueError:
|
|
pass
|
|
|
|
if in_stock_only:
|
|
query = query.filter(Product.stock > 0)
|
|
|
|
if sort_by == 'price_low':
|
|
query = query.order_by(Product.price.asc())
|
|
elif sort_by == 'price_high':
|
|
query = query.order_by(Product.price.desc())
|
|
elif sort_by == 'name':
|
|
query = query.order_by(Product.name.asc())
|
|
elif sort_by == 'rating':
|
|
|
|
query = query.order_by(Product.id.desc())
|
|
else:
|
|
query = query.order_by(Product.id.desc())
|
|
|
|
colors = db.session.query(Product.color).distinct().filter(
|
|
Product.color != None, Product.color != '').all()
|
|
colors = [c[0] for c in colors if c[0]]
|
|
|
|
materials = db.session.query(Product.material).distinct().filter(
|
|
Product.material != None, Product.material != '').all()
|
|
materials = [m[0] for m in materials if m[0]]
|
|
|
|
companies = db.session.query(Product.company).distinct().filter(
|
|
Product.company != None, Product.company != '').all()
|
|
companies = [c[0] for c in companies if c[0]]
|
|
|
|
products = query.all()
|
|
|
|
categories = Category.query.order_by(Category.name.asc()).all()
|
|
|
|
return render_template('products.html',
|
|
products=products,
|
|
categories=categories,
|
|
sizes=SizeEnum.ALL,
|
|
colors=colors,
|
|
materials=materials,
|
|
companies=companies,
|
|
search_query=search_query,
|
|
selected_category=category_id,
|
|
selected_category_name=selected_category_name,
|
|
selected_size=size,
|
|
selected_color=color,
|
|
selected_material=material,
|
|
selected_company=company,
|
|
min_price=min_price,
|
|
max_price=max_price,
|
|
sort_by=sort_by,
|
|
in_stock_only=in_stock_only)
|
|
|
|
@main_bp.route('/product/<int:id>')
|
|
def product_detail(id):
|
|
product = Product.query.get_or_404(id)
|
|
|
|
|
|
related_products = Product.query.filter(
|
|
Product.category_id == product.category_id,
|
|
Product.id != product.id
|
|
).limit(4).all()
|
|
|
|
return render_template('product_detail.html',
|
|
product=product,
|
|
related_products=related_products)
|