Files
wearwell/models.py
2026-01-30 14:02:35 +03:30

197 lines
6.5 KiB
Python

import os
from datetime import datetime
from flask_login import UserMixin
from werkzeug.security import check_password_hash, generate_password_hash
from extensions import db
class SizeEnum:
XS = 'XS'
S = 'S'
M = 'M'
L = 'L'
XL = 'XL'
XXL = 'XXL'
XXXL = 'XXXL'
ALL = [XS, S, M, L, XL, XXL, XXXL]
class CategoryEnum:
T_SHIRTS = 'T-Shirts'
SHIRTS = 'Shirts'
JEANS = 'Jeans'
PANTS = 'Pants'
JACKETS = 'Jackets'
HOODIES = 'Hoodies'
SWEATERS = 'Sweaters'
SHORTS = 'Shorts'
DRESSES = 'Dresses'
SKIRTS = 'Skirts'
ACTIVEWEAR = 'Activewear'
SHOES = 'Shoes'
ACCESSORIES = 'Accessories'
ALL = [
T_SHIRTS, SHIRTS, JEANS, PANTS, JACKETS, HOODIES,
SWEATERS, SHORTS, DRESSES, SKIRTS, ACTIVEWEAR,
SHOES, ACCESSORIES
]
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(255))
is_admin = db.Column(db.Boolean, default=False)
cart = db.relationship('Cart', backref='user', uselist=False)
orders = db.relationship('Order', backref='user', lazy=True)
reviews = db.relationship('Review', backref='user', lazy=True)
likes = db.relationship('ProductLike', 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 Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
products = db.relationship('Product', backref='category', lazy=True)
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), nullable=False)
description = db.Column(db.Text)
price = db.Column(db.Float, nullable=False)
stock = db.Column(db.Integer, default=0)
color = db.Column(db.String(50))
size = db.Column(db.String(10))
material = db.Column(db.String(50))
company = db.Column(db.String(100))
sku = db.Column(db.String(50), unique=True)
weight = db.Column(db.Float)
dimensions = db.Column(db.String(50))
category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
images = db.relationship(
'ProductImage', backref='product', lazy=True, cascade="all, delete-orphan")
reviews = db.relationship('Review', backref='product',
lazy=True, cascade="all, delete-orphan")
likes = db.relationship('ProductLike', backref='product',
lazy=True, cascade="all, delete-orphan")
@property
def average_rating(self):
if not self.reviews:
return 0
total = sum(review.rating for review in self.reviews)
return round(total / len(self.reviews), 1)
@property
def like_count(self):
return len([like for like in self.likes if like.is_like])
@property
def dislike_count(self):
return len([like for like in self.likes if not like.is_like])
@property
def review_count(self):
return len(self.reviews)
@property
def primary_image(self):
if self.images:
primary = next((img for img in self.images if img.is_primary), None)
if primary:
return primary
return self.images[0]
return None
def get_image_url(self):
"""Alias for template compatibility"""
return self.get_primary_image_url()
def in_stock(self):
return self.stock > 0
def get_primary_image_url(self):
primary = self.primary_image
if primary:
return f"/static/uploads/products/{primary.filename}"
return "/static/images/default-product.jpg"
def get_all_image_urls(self):
return [f"/static/uploads/products/{img.filename}" for img in self.images]
def __repr__(self):
return f'<Product {self.name}>'
class ProductImage(db.Model):
id = db.Column(db.Integer, primary_key=True)
product_id = db.Column(
db.Integer, db.ForeignKey('product.id'), nullable=False)
filename = db.Column(db.String(200), nullable=False)
is_primary = db.Column(db.Boolean, default=False)
display_order = db.Column(db.Integer, default=0)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
class ProductLike(db.Model):
id = db.Column(db.Integer, primary_key=True)
product_id = db.Column(
db.Integer, db.ForeignKey('product.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
is_like = db.Column(db.Boolean, default=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
__table_args__ = (db.UniqueConstraint(
'product_id', 'user_id', name='unique_product_user_like'),)
class Review(db.Model):
id = db.Column(db.Integer, primary_key=True)
product_id = db.Column(
db.Integer, db.ForeignKey('product.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
rating = db.Column(db.Integer, nullable=False)
title = db.Column(db.String(200))
comment = db.Column(db.Text)
is_verified_purchase = db.Column(db.Boolean, default=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, onupdate=datetime.utcnow)
class Cart(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
items = db.relationship('CartItem', backref='cart',
cascade="all, delete-orphan", lazy=True)
class CartItem(db.Model):
id = db.Column(db.Integer, primary_key=True)
cart_id = db.Column(db.Integer, db.ForeignKey('cart.id'))
product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
quantity = db.Column(db.Integer, default=1)
selected_size = db.Column(db.String(10))
selected_color = db.Column(db.String(50))
product = db.relationship('Product')
class Order(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
created_at = db.Column(db.DateTime, default=datetime.utcnow)
status = db.Column(db.String(50), default='pending')
items = db.relationship('OrderItem', backref='order',
cascade='all, delete-orphan', lazy=True)
class OrderItem(db.Model):
id = db.Column(db.Integer, primary_key=True)
order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
quantity = db.Column(db.Integer, default=1)
price_at_purchase = db.Column(db.Float)
selected_size = db.Column(db.String(10))
selected_color = db.Column(db.String(50))
product = db.relationship('Product')