Skip to content

Commit

Permalink
Merge pull request #78 from Andrenord282/main
Browse files Browse the repository at this point in the history
feat: database migration,template displays cards from the database
  • Loading branch information
RyjkovAlexey committed Mar 17, 2024
2 parents cc52e5b + e76182b commit 42161da
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 114 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.idea

/animals_photo/
/node_modules/
/frontend/node_modules/
/frontend/testing/
/animal_photos/
2 changes: 1 addition & 1 deletion backend/dao/base_dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(

async def find_all(self):
query = select(self.model)
return (await self.session.execute(query)).scalars().all()
return (await self.session.execute(query)).unique().scalars().all()

async def find_one(self, model_id):
query = select(self.model)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""add additional fields to models
Revision ID: 3e3431180c42
Revises: 619cced1d961
Create Date: 2024-03-15 22:33:02.438735
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '3e3431180c42'
down_revision: Union[str, None] = '619cced1d961'
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.add_column('animal', sa.Column('type', sa.String(), nullable=False))
op.add_column('animal', sa.Column('sex', sa.String(), nullable=False))
op.add_column('animal', sa.Column('age', sa.String(), nullable=False))
op.add_column('animal', sa.Column('size', sa.String(), nullable=False))
op.create_unique_constraint(op.f('uq__animal__id'), 'animal', ['id'])
op.drop_index('ix__photo__animal_id', table_name='animal_photo')
op.drop_index('ix__photo__id', table_name='animal_photo')
op.create_index(op.f('ix__animal_photo__animal_id'), 'animal_photo', ['animal_id'], unique=False)
op.create_index(op.f('ix__animal_photo__id'), 'animal_photo', ['id'], unique=True)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix__animal_photo__id'), table_name='animal_photo')
op.drop_index(op.f('ix__animal_photo__animal_id'), table_name='animal_photo')
op.create_index('ix__photo__id', 'animal_photo', ['id'], unique=False)
op.create_index('ix__photo__animal_id', 'animal_photo', ['animal_id'], unique=False)
op.drop_constraint(op.f('uq__animal__id'), 'animal', type_='unique')
op.drop_column('animal', 'size')
op.drop_column('animal', 'age')
op.drop_column('animal', 'sex')
op.drop_column('animal', 'type')
# ### end Alembic commands ###
26 changes: 26 additions & 0 deletions backend/models/animal.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from sqlalchemy import Integer, Column, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.hybrid import hybrid_property
from backend.settings import Settings
from backend.database.metadata import DeclarativeBase


Expand All @@ -9,3 +11,27 @@ class Animal(DeclarativeBase):
id = Column(Integer, primary_key=True, autoincrement=True, unique=True)
name_ru = Column(String, nullable=False)
name_en = Column(String, nullable=False)
type = Column(String, nullable=False)
sex = Column(String, nullable=False)
age = Column(String, nullable=False)
size = Column(String, nullable=False)
photos = relationship(
"AnimalPhoto",
back_populates="animal",
primaryjoin="AnimalPhoto.animal_id == Animal.id",
lazy="joined",
)

@hybrid_property
def link(self):
settings = Settings()
return f"http://{settings.APP_HOST}:{settings.APP_PORT}/animals/animal/{self.id}"

@hybrid_property
def img_src(self):
return self.photos[0].full_url if self.photos and self.photos[0] else ''

@hybrid_property
def name(self):
return self.name_en

2 changes: 2 additions & 0 deletions backend/models/animal_photo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sqlalchemy import Integer, Column, String, ForeignKey
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import relationship
from backend.database.metadata import DeclarativeBase
from backend.settings import Settings

Expand All @@ -11,6 +12,7 @@ class AnimalPhoto(DeclarativeBase):
url = Column(String, nullable=False)

animal_id = Column(Integer, ForeignKey('animal.id', ondelete="CASCADE"), nullable=False, index=True)
animal = relationship('Animal', foreign_keys=[animal_id], lazy="noload")

@hybrid_property
def full_url(self):
Expand Down
3 changes: 2 additions & 1 deletion backend/routers/animal_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
async def get_index_template(
request: Request,
) -> HTMLResponse:
return AnimalTemplateService(request).get_index_template()
async with request.app.state.db.get_master_session() as session:
return await AnimalTemplateService(request, session).get_index_template()


@router.get("/")
Expand Down
14 changes: 13 additions & 1 deletion backend/schemas/animal_schemas.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
from backend.schemas.base_schema import BaseSchema


class AnimalIndexSchema(BaseSchema):
link: str = '#'
type: str
img_src: str
name: str
sex: str
age: str
size: str

class AnimalBaseSchema(BaseSchema):
name_ru: str
name_en: str
Expand All @@ -11,7 +20,10 @@ class AnimalResponseSchema(AnimalBaseSchema):


class AnimalCreateSchema(AnimalBaseSchema):
...
type: str
sex: str
age: str
size: str


class AnimalUpdateSchema(AnimalBaseSchema):
Expand Down
13 changes: 9 additions & 4 deletions backend/services/animal_template_service.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
from fastapi.responses import HTMLResponse
from backend.dao.animal_dao import AnimalDao
from backend.models.animal import Animal
from backend.services.base_template_service import BaseTemplateService
from backend.schemas.animal_schemas import AnimalIndexSchema


class AnimalTemplateService(BaseTemplateService):
def __init__(self, request):
super().__init__(request)
def __init__(self, request, session):
super().__init__(request, session)

@staticmethod
def _complete_template_path(template_name: str):
return f"pages/index/{template_name}"

def get_index_template(self) -> HTMLResponse:
async def get_index_template(self) -> HTMLResponse:
animals:list[Animal] = await AnimalDao(self.session).find_all()
cards = [AnimalIndexSchema.from_orm(animal) for animal in animals]
return self.templates.TemplateResponse(
name=self._complete_template_path("index.html"),
context={"request": self.request}
context={"request": self.request, "cards": cards}
)
4 changes: 3 additions & 1 deletion backend/services/base_template_service.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from fastapi import Request
from fastapi.templating import Jinja2Templates
from sqlalchemy.ext.asyncio import AsyncSession as Session


class BaseTemplateService:
templates = Jinja2Templates(directory="./backend/templates")

def __init__(self, request: Request):
def __init__(self, request: Request, session: Session | None):
self.request = request
self.session = session
2 changes: 1 addition & 1 deletion backend/settings/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Settings(BaseSettings):
DB_PORT: str | None = "5432"
DB_USER: str | None = "postgres"
DB_PASSWORD: str | None = "postgres"
DB_NAME: str | None = "shelterpaws-testing-db"
DB_NAME: str | None = "postgres"

APP_HOST: str | None = "0.0.0.0"
APP_PORT: int | None = 8080
Expand Down
21 changes: 11 additions & 10 deletions backend/templates/general/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,29 @@

{% from "ui/buttons.html" import button %}

{% set header_databag = { 'shelter_name': "Territory Of Goodness", 'menu_items': [{ 'title': "Main", 'link': "#" }, { 'title': "Contacts", 'link': "#contacts" }, { 'title': "Donations", 'link': "#donations" }, { 'title': "Adopted", 'link': "#adopted" }] } %}
{% set header_databag = { 'shelter_name': "Territory Of Goodness", 'menu_items':
[{ 'title': "Main", 'link': "#" }, { 'title': "Contacts", 'link': "#contacts" },
{ 'title': "Donations", 'link': "#donations" }, { 'title': "Adopted", 'link':
"#adopted" }] } %}
<header class="page-header">
<div class="page-header__in">
<p class="page-header__logo">{{ header_databag.shelter_name }}</p>

<ul class="page-menu">
{% for item in header_databag.menu_items %}
<li class="page-menu__item">
<a class="page-menu__link" href="{{ item.link }}">{{ item.title }}</a>
</li>
<li class="page-menu__item">
<a class="page-menu__link" href="{{ item.link }}">{{ item.title }}</a>
</li>
{% endfor %}


{{ button("Donate", { "size": "s", "icon": 'donate' }) }}

{{ button("Donate", { "size": "s", "icon": 'donate' }) }}

</ul>

<button class="burger">
<span class="burger__dash"></span>
<span class="burger__dash"></span>
<span class="burger__dash"></span>
<span class="burger__dash"></span>
<span class="burger__dash"></span>
<span class="burger__dash"></span>
</button>
</div>
</header>
Expand Down
93 changes: 1 addition & 92 deletions backend/templates/pages/index/sections/animals_section.html
Original file line number Diff line number Diff line change
@@ -1,97 +1,6 @@
{% from "ui/section_header.html" import section_header with context %}
{% from "ui/animal_card.html" import animal_card %}
{% set cards = [
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-01.jpg',
'name': 'Spot',
'sex': 'Male',
'age': '18 months',
'size': 'Large'
},
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-02.jpg',
'name': 'Shaggy',
'sex': 'Male',
'age': '8 years',
'size': 'Large'
},
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-03.jpg',
'name': 'Ulybashka',
'sex': 'Female',
'age': '1 year',
'size': 'Medium'
},
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-04.jpg',
'name': 'Boy',
'sex': 'Male',
'age': '2 years',
'size': 'Medium'
},
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-05.jpg',
'name': 'Betty',
'sex': 'Feale',
'age': '2 years',
'size': 'Large'
},
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-01.jpg',
'name': 'Spot',
'sex': 'Male',
'age': '18 months',
'size': 'Large'
},
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-03.jpg',
'name': 'Ulybashka',
'sex': 'Female',
'age': '1 year',
'size': 'Medium'
},
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-02.jpg',
'name': 'Shaggypot',
'sex': 'Male',
'age': '8 years',
'size': 'Large'
},
{
'link': '#',
'type': 'dogs',
'img_src': '/upload/animal-cards/card-04.jpg',
'name': 'Boy',
'sex': 'Male',
'age': '2 years',
'size': 'Medium'
},
{
'link': '#',
'type': 'cats',
'img_src': '/upload/animal-cards/card-06.jpg',
'name': 'Basil',
'sex': 'Male',
'age': '1 years',
'size': 'Medium'
}
] %}

<section class="animals-section" id="adopted">
<div class="container animals-section__container">
<div class="animals-section__content">
Expand Down
4 changes: 2 additions & 2 deletions backend/templates/pages/index/sections/statistic_section.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{% set statisticData = [
{
'text': 'Pets at the shelter',
'value': '218'
'value': '53'
}, {
'text': 'Happy Pets adopted',
'value': '167'
'value': '14'
}
] %}

Expand Down

0 comments on commit 42161da

Please sign in to comment.