filter's fix

This commit is contained in:
Daniel Haus 2026-02-11 15:43:30 +03:00
parent ff50ea6784
commit 4b4acdcb1b
6 changed files with 144 additions and 171 deletions

View file

@ -1,36 +1,23 @@
import psycopg2
from psycopg2.extras import RealDictCursor
from config import (
DB_HOST,
DB_PORT,
DB_NAME,
DB_USER,
DB_PASSWORD,
)
class Database:
def __init__(self):
self.connection = psycopg2.connect(
host=DB_HOST,
port=DB_PORT,
dbname=DB_NAME,
user=DB_USER,
password=DB_PASSWORD,
cursor_factory=RealDictCursor,
def __init__(self, dbname, user, password, host="localhost", port=5432):
self.conn = psycopg2.connect(
dbname=dbname, user=user, password=password, host=host, port=port
)
def fetch_all(self, query: str, params: tuple = ()):
with self.connection.cursor() as cursor:
cursor.execute(query, params)
return cursor.fetchall()
def query(self, sql, params=None):
with self.conn.cursor() as cur:
cur.execute(sql, params or ())
if cur.description:
return cur.fetchall()
return None
def fetch_one(self, query: str, params: tuple = ()):
with self.connection.cursor() as cursor:
cursor.execute(query, params)
return cursor.fetchone()
def fetch_one(self, sql, params=None):
with self.conn.cursor() as cur:
cur.execute(sql, params or ())
return cur.fetchone()
def execute(self, query: str, params: tuple = ()):
with self.connection.cursor() as cursor:
cursor.execute(query, params)
self.connection.commit()
def commit(self):
self.conn.commit()

View file

@ -1,87 +1,47 @@
from models.database import Database
class ToyModel:
def __init__(self, database: Database):
self.database = database
def __init__(self, database: "Database"):
self.db = database
def get_all(self):
query = """
SELECT t.toy_id,
t.toy_name,
c.category_name,
m.manufacturer_name,
t.price,
t.discount,
COALESCE(s.quantity, 0) AS quantity,
STRING_AGG(DISTINCT a.age_label, ', ') AS ages,
STRING_AGG(DISTINCT sup.supplier_name, ', ') AS suppliers
sql = """
SELECT t.toy_name, c.category_name, m.manufacturer_name,
STRING_AGG(DISTINCT ag.age_label, ', ') AS ages,
STRING_AGG(DISTINCT s.supplier_name, ', ') AS suppliers,
t.price, t.discount, st.quantity
FROM toys t
JOIN categories c ON t.category_id = c.category_id
JOIN manufacturers m ON t.manufacturer_id = m.manufacturer_id
LEFT JOIN stock s ON t.toy_id = s.toy_id
LEFT JOIN toy_age_groups ta ON t.toy_id = ta.toy_id
LEFT JOIN age_groups a ON ta.age_group_id = a.age_group_id
LEFT JOIN toy_age_groups tag ON t.toy_id = tag.toy_id
LEFT JOIN age_groups ag ON tag.age_group_id = ag.age_group_id
LEFT JOIN toy_suppliers ts ON t.toy_id = ts.toy_id
LEFT JOIN suppliers sup ON ts.supplier_id = sup.supplier_id
GROUP BY t.toy_id, c.category_name,
m.manufacturer_name, s.quantity
ORDER BY t.toy_name
LEFT JOIN suppliers s ON ts.supplier_id = s.supplier_id
LEFT JOIN stock st ON t.toy_id = st.toy_id
GROUP BY t.toy_id, c.category_name, m.manufacturer_name, t.price, t.discount, st.quantity
ORDER BY t.toy_id
"""
return self.database.fetch_all(query)
rows = self.db.query(sql)
toys = []
for r in rows:
toys.append({
"toy_name": r[0],
"category_name": r[1],
"manufacturer_name": r[2],
"ages": r[3] or "",
"suppliers": r[4] or "",
"price": float(r[5]),
"discount": int(r[6]),
"quantity": int(r[7] or 0),
})
return toys
def search_by_age(self, age: str):
query = """
SELECT *
FROM (
SELECT t.toy_id,
t.toy_name,
c.category_name,
m.manufacturer_name,
t.price,
t.discount,
COALESCE(s.quantity, 0) AS quantity,
STRING_AGG(DISTINCT a.age_label, ', ') AS ages,
STRING_AGG(DISTINCT sup.supplier_name, ', ') AS suppliers
FROM toys t
JOIN categories c ON t.category_id = c.category_id
JOIN manufacturers m ON t.manufacturer_id = m.manufacturer_id
LEFT JOIN stock s ON t.toy_id = s.toy_id
LEFT JOIN toy_age_groups ta ON t.toy_id = ta.toy_id
LEFT JOIN age_groups a ON ta.age_group_id = a.age_group_id
LEFT JOIN toy_suppliers ts ON t.toy_id = ts.toy_id
LEFT JOIN suppliers sup ON ts.supplier_id = sup.supplier_id
GROUP BY t.toy_id, c.category_name,
m.manufacturer_name, s.quantity
) sub
WHERE ages ILIKE %s
"""
return self.database.fetch_all(query, (f"%{age}%",))
def sort_by_price(self, ascending=True):
toys = self.get_all()
return sorted(toys, key=lambda x: x["price"], reverse=not ascending)
def sort_by_price(self):
query = """
SELECT *
FROM (
SELECT t.toy_id,
t.toy_name,
c.category_name,
m.manufacturer_name,
t.price,
t.discount,
COALESCE(s.quantity, 0) AS quantity,
STRING_AGG(DISTINCT a.age_label, ', ') AS ages,
STRING_AGG(DISTINCT sup.supplier_name, ', ') AS suppliers
FROM toys t
JOIN categories c ON t.category_id = c.category_id
JOIN manufacturers m ON t.manufacturer_id = m.manufacturer_id
LEFT JOIN stock s ON t.toy_id = s.toy_id
LEFT JOIN toy_age_groups ta ON t.toy_id = ta.toy_id
LEFT JOIN age_groups a ON ta.age_group_id = a.age_group_id
LEFT JOIN toy_suppliers ts ON t.toy_id = ts.toy_id
LEFT JOIN suppliers sup ON ts.supplier_id = sup.supplier_id
GROUP BY t.toy_id, c.category_name,
m.manufacturer_name, s.quantity
) sub
ORDER BY price
"""
return self.database.fetch_all(query)
def get_age_groups(self):
rows = self.db.query("SELECT age_label FROM age_groups ORDER BY age_group_id")
return [r[0] for r in rows]
def get_suppliers(self):
rows = self.db.query("SELECT supplier_name FROM suppliers ORDER BY supplier_id")
return [r[0] for r in rows]

View file

@ -1,17 +1,23 @@
from models.database import Database
class UserModel:
def __init__(self, database: Database):
self.database = database
def __init__(self, database):
self.db = database
def authenticate(self, login: str, password: str):
query = """
SELECT u.user_id,
u.full_name,
r.role_name
def authenticate(self, login, password):
sql = """
SELECT u.login, u.password, u.full_name, r.role_name
FROM users u
JOIN roles r ON u.role_id = r.role_id
WHERE u.login = %s AND u.password = %s
"""
return self.database.fetch_one(query, (login, password))
row = self.db.fetch_one(sql, (login, password))
if row:
return {
"login": row[0],
"password": row[1],
"full_name": row[2],
"role_name": row[3],
}
return None