Ratings table added

This commit is contained in:
Dmitry 2024-09-04 20:32:49 +03:00
parent 0094b18ddc
commit 22a6cf8028
6 changed files with 121 additions and 55 deletions

View File

@ -57,39 +57,6 @@ async def filter_ann(schema: pydantic_schemas.SortAnnouncements, db: AsyncSessio
filter_query = await db.execute(select(orm_models.Announcement).where(literal_column(f"announcements.{name}") == filt_val)) filter_query = await db.execute(select(orm_models.Announcement).where(literal_column(f"announcements.{name}") == filt_val))
filtered = set(filter_query.scalars().all()) filtered = set(filter_query.scalars().all())
res = res.intersection(filtered) res = res.intersection(filtered)
# # отфильтровываем подходящие объявления
# res = await db.execute(
# select(orm_models.Announcement).where(
# ((schema.obsolete == None) | ((schema.obsolete != None) & (orm_models.Announcement.obsolete == schema.obsolete)))
# & ((schema.user_id == None) | ((schema.user_id != None) & (orm_models.Announcement.user_id == schema.user_id)))
# & ((schema.metro == None) | ((schema.metro != None) & (orm_models.Announcement.metro == schema.metro)))
# & ((schema.category == None) | ((schema.category != None) & (orm_models.Announcement.category == schema.category)))
# )
# )
# .where(schema.user_id != None and orm_models.Announcement.user_id == schema.user_id)
# .where(schema.metro != None and orm_models.Announcement.metro == schema.metro)
# .where(schema.category != None and orm_models.Announcement.category == schema.category)
# statement = text("SELECT * FROM announcements "
# "WHERE announcements.obsolete = :obsolete "
# "INTERSECT"
# "SELECT * FROM announcements "
# "WHERE announcements.user_id == :user_id "
# "INTERSECT"
# "SELECT * FROM announcements "
# "WHERE announcements.metro == :metro "
# "INTERSECT"
# "SELECT * FROM announcements "
# "WHERE announcements.category == :category")
# res = await db.execute(statement,
# {"obsolete": schema.obsolete,
# "user_id": schema.user_id,
# "metro": schema.metro,
# "category": schema.category}
# )
# возвращаем все подходящие объявления # возвращаем все подходящие объявления
return res return res

View File

@ -43,33 +43,66 @@ if not os.path.exists("./uploads"):
# создаем эндпоинт для хранения файлов пользователя # создаем эндпоинт для хранения файлов пользователя
app.mount("/uploads", StaticFiles(directory = "./uploads")) app.mount("/uploads", StaticFiles(directory = "./uploads"))
# эндпоинт для возвращения согласия в pdf # эндпоинт для возвращения согласия в pdf
@app.get("/privacy_policy.pdf") @app.get("/privacy_policy.pdf")
async def privacy_policy(): async def privacy_policy():
return FileResponse("./privacy_policy.pdf") return FileResponse("./privacy_policy.pdf")
# получение списка объявлений # получение списка объявлений
@app.get("/api/announcements", response_model=List[pydantic_schemas.Announcement])#адрес объявлений @app.get("/api/announcements", response_model=List[pydantic_schemas.Announcement])
async def announcements_list(db: Annotated[Session, Depends(auth_utils.get_session)], obsolete: Union[bool, None] = False, user_id: Union[int, None] = None, async def announcements_list(db: Annotated[Session, Depends(auth_utils.get_session)],
metro: Union[str, None] = None,category: Union[str, None] = None): current_user: Annotated[pydantic_schemas.User, Depends(auth_utils.get_current_active_user)],
obsolete: Union[bool, None] = False, user_id: Union[int, None] = None, metro: Union[str, None] = None,
category: Union[str, None] = None):
# параметры для сортировки (схема pydantic schemas.SortAnnouncements) # параметры для сортировки (схема pydantic schemas.SortAnnouncements)
params_to_sort = pydantic_schemas.SortAnnouncements(obsolete=obsolete, user_id=user_id, metro=metro, category=category) params_to_sort = pydantic_schemas.SortAnnouncements(obsolete=obsolete, user_id=user_id, metro=metro, category=category)
# получаем результат # получаем результат (значения с определенными полями obsolete, user_id, metro, category).
# user_id - id пользователя, которому принадлежат объявления
result = await add_poems_and_filters.filter_ann(db=db, schema=params_to_sort) result = await add_poems_and_filters.filter_ann(db=db, schema=params_to_sort)
return result # для каждого отфильтрованного объявления проверяем, забронировано ли оно текущим пользователем и в зависимости
# от этого флаг booked_by_current_user устанавливаем в 0 или в 1
check_if_booked = [pydantic_schemas.Announcement.from_orm(elem) for elem in result]
for an in check_if_booked:
# ищем пару с заданными id объявления и id текущего пользователя
query = await db.execute(select(orm_models.AnnouncementUser).where(
orm_models.AnnouncementUser.announcement_id == an.id).where(
orm_models.AnnouncementUser.booking_user_id == current_user.id))
pair_found = query.scalars().first()
if pair_found:
an.booked_by_current_user = True
else:
an.booked_by_current_user = False
return check_if_booked
# получаем данные одного объявления # получаем данные одного объявления
@app.get("/api/announcement", response_model=pydantic_schemas.AnnResponce) @app.get("/api/announcement", response_model=pydantic_schemas.AnnResponce)
async def single_announcement(ann_id:int, db: Annotated[Session, Depends(auth_utils.get_session)]): # передаем индекс обявления async def single_announcement(ann_id:int, db: Annotated[Session, Depends(auth_utils.get_session)],
current_user: Annotated[pydantic_schemas.User, Depends(auth_utils.get_current_active_user)]):
# Считываем данные из Body и отображаем их на странице. # Считываем данные из Body и отображаем их на странице.
# В последствии будем вставлять данные в html-форму # В последствии будем вставлять данные в html-форму
announcement = await db.get(orm_models.Announcement, ann_id) announcement = await db.get(orm_models.Announcement, ann_id)
#announcement = await db.execute(select(orm_models.Announcement)).scalars().all() #announcement = await db.execute(select(orm_models.Announcement)).scalars().all()
if not announcement: if not announcement:
raise HTTPException(status_code=404, detail="Item not found") raise HTTPException(status_code=404, detail="Item not found")
return announcement
# создаем форму pydantic_schemas.AnnResponce из ORM-объекта announcement
announcement_model = pydantic_schemas.AnnResponce.from_orm(announcement)
# ищем пару с заданными id объявления и id текущего пользователя
query = await db.execute(select(orm_models.AnnouncementUser).where(
orm_models.AnnouncementUser.announcement_id == announcement.id).where(
orm_models.AnnouncementUser.booking_user_id == current_user.id))
pair_found = query.scalars().first()
# если такая пара найдена, записываем в поле booked_by_current_user True
if pair_found:
announcement_model.booked_by_current_user = True
return announcement_model
# Занести объявление в базу данных # Занести объявление в базу данных
@ -153,7 +186,7 @@ async def change_book_status(data: pydantic_schemas.Book, current_user: Annotate
new_pair = orm_models.AnnouncementUser(announcement_to_change.id, current_user.id) new_pair = orm_models.AnnouncementUser(announcement_to_change.id, current_user.id)
# Инкрементируем поле booked_counter на 1 # Инкрементируем поле booked_counter на 1
announcement_to_change.booked_counter += 1 announcement_to_change.booked_counter += 1
# вставляем индекс забронировавшего пользователя в поле booked_by # добавляем запись в таблицу announcementuser
db.add(new_pair) db.add(new_pair)
# фиксируем изменения в бд # фиксируем изменения в бд

View File

@ -37,17 +37,11 @@ class Announcement(Base): #класс объявления
src = Column(String, nullable=True) #изображение продукта в объявлении src = Column(String, nullable=True) #изображение продукта в объявлении
metro = Column(String) #ближайщее метро от адреса нахождения продукта metro = Column(String) #ближайщее метро от адреса нахождения продукта
trashId = Column(Integer, nullable=True) trashId = Column(Integer, nullable=True)
booked_by = Column(Integer, nullable=True) # id пользователя, забронировавшего объявление
booked_counter = Column(Integer, nullable=True) #количество забронировавших (0 - никто не забронировал) booked_counter = Column(Integer, nullable=True) #количество забронировавших (0 - никто не забронировал)
obsolete = Column(Boolean, default=False) # состояние объявления (по-умолчанию считаем его актуальным) obsolete = Column(Boolean, default=False) # состояние объявления (по-умолчанию считаем его актуальным)
user = relationship("User", secondary="announcementuser", back_populates="announcements") user = relationship("User", secondary="announcementuser", back_populates="announcements")
# Класс пары, хранящей id объявления и id забронировавшего юзера
@dataclasses.dataclass
class UserAnouncementPair:
announcement_id: int
booking_user_id: int
class AnnouncementUser(Base): class AnnouncementUser(Base):
__tablename__ = "announcementuser" __tablename__ = "announcementuser"
@ -61,11 +55,17 @@ class AnnouncementUser(Base):
# class Ratings(Base): class Ratings(Base):
# __tablename__ = "ratings" __tablename__ = "ratings"
# rated_user_id = Column(Integer, primary_key=True) # id пользователя, оставившего оценку def __init__(self, rated_user_id, user_giving_rating_id, rating_val):
# rating_value = Column(Integer, primary_key=True) # оценка self.rated_user_id = rated_user_id
self.user_giving_rating_id = user_giving_rating_id
self.rating_value = rating_val
rated_user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) # id пользователя, оставившего оценку
user_giving_rating_id = Column(Integer, ForeignKey("users.id"), primary_key=True) # id оцениваемого пользователя
rating_value = Column(Integer, primary_key=True) # оценка
class Trashbox(Base): #класс мусорных баков class Trashbox(Base): #класс мусорных баков

View File

@ -1,8 +1,7 @@
from pydantic import BaseModel from pydantic import BaseModel
from typing import Annotated, Union from typing import Union
from datetime import date from datetime import date
from typing import List from typing import List
from fastapi import UploadFile, Form
class Book(BaseModel): class Book(BaseModel):
id: int id: int
@ -28,7 +27,7 @@ class Announcement(BaseModel):
src: Union[str, None] = None #изображение продукта в объявлении src: Union[str, None] = None #изображение продукта в объявлении
metro: str #ближайщее метро от адреса нахождения продукта metro: str #ближайщее метро от адреса нахождения продукта
trashId: Union[int, None] = None trashId: Union[int, None] = None
booked_by: Union[int, None] = 0 #статус бронирования (либо 0, либо айди бронирующего) booked_by_current_user: Union[bool, None] = False
obsolete: bool obsolete: bool
class Config: class Config:
@ -50,7 +49,7 @@ class AnnResponce(BaseModel):
src: Union[str, None] = None #изображение продукта в объявлении src: Union[str, None] = None #изображение продукта в объявлении
metro: str #ближайщее метро от адреса нахождения продукта metro: str #ближайщее метро от адреса нахождения продукта
trashId: Union[int, None] = None trashId: Union[int, None] = None
booked_by: Union[int, None] = 0 #статус бронирования (либо 0, либо айди бронирующего) booked_by_current_user: Union[bool, None] = False
class Config: class Config:
orm_mode = True orm_mode = True

View File

@ -0,0 +1,37 @@
"""Many to many relationship Rating added
Revision ID: a309e6ee6307
Revises: cf0525fd49a8
Create Date: 2024-08-28 22:08:08.399530
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'a309e6ee6307'
down_revision: Union[str, None] = 'cf0525fd49a8'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('ratings',
sa.Column('rated_user_id', sa.Integer(), nullable=False),
sa.Column('user_giving_rating_id', sa.Integer(), nullable=False),
sa.Column('rating_value', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['rated_user_id'], ['users.id'], ),
sa.ForeignKeyConstraint(['user_giving_rating_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('rated_user_id', 'user_giving_rating_id', 'rating_value')
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('ratings')
# ### end Alembic commands ###

View File

@ -0,0 +1,30 @@
"""booked_by column removed in Announcements table
Revision ID: cf0525fd49a8
Revises: 19dbd9793f11
Create Date: 2024-08-28 21:59:23.787732
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'cf0525fd49a8'
down_revision: Union[str, None] = '19dbd9793f11'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('announcements', 'booked_by')
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('announcements', sa.Column('booked_by', sa.INTEGER(), autoincrement=False, nullable=True))
# ### end Alembic commands ###