diff --git a/blog/admin/__init__.py b/blog/admin/__init__.py index 6f4c44e..cb6c034 100644 --- a/blog/admin/__init__.py +++ b/blog/admin/__init__.py @@ -5,7 +5,7 @@ from blog.category.models import Category from blog.extensions import db -from blog.post.models import Post +from blog.post.models import Post, Icon from blog.tags.models import Tag from blog.user.models import User @@ -40,5 +40,6 @@ def create_admin(config_admin): config_admin.add_view(UserView(Category, db.session, endpoint="")) config_admin.add_view(UserView(Tag, db.session, endpoint="")) config_admin.add_view(UserView(User, db.session, endpoint="")) + config_admin.add_view(UserView(Icon, db.session, endpoint="")) path = os.path.join(os.path.dirname(__file__), "../static/upload") config_admin.add_view(MyFileAdmin(path, "/static/upload", name="files")) diff --git a/blog/post/models.py b/blog/post/models.py index d841662..f5dd3d0 100644 --- a/blog/post/models.py +++ b/blog/post/models.py @@ -1,6 +1,7 @@ # blog/posts/models.py import datetime -from typing import TYPE_CHECKING, List +from typing import TYPE_CHECKING +import typing import markdown from sqlalchemy import DateTime, ForeignKey, Text @@ -22,9 +23,10 @@ class Post(db.Model): """orm model for blog post.""" - __tablename__ = "posts" + __tablename__ = "posts" # pyright: ignore[reportUnannotatedClassAttribute] + id: Mapped[int] = mapped_column(primary_key=True) - pagetitle: Mapped[str] + pagetitle: Mapped[str] = mapped_column(nullable=False, unique=False) alias: Mapped[str] = mapped_column(nullable=False, unique=True) content: Mapped[str] = mapped_column(type_=Text) createdon: Mapped[datetime.datetime] = mapped_column( @@ -39,7 +41,7 @@ class Post(db.Model): user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=True) user: Mapped["User"] = relationship(back_populates="posts") category: Mapped["Category"] = relationship(back_populates="posts") - tags: Mapped[List["Tag"]] = relationship( + tags: Mapped[list["Tag"]] = relationship( secondary=posts_tags, back_populates="posts" ) @@ -47,5 +49,22 @@ class Post(db.Model): def markdown(self): return markdown.markdown(self.content, extensions=MARKDOWN_EXTENSIONS) + @typing.override def __str__(self): return f"{self.pagetitle}" + + +class Icon(db.Model): + """orm model for icons.""" + + __tablename__ = "icons" # pyright: ignore[reportUnannotatedClassAttribute] + + id: Mapped[int] = mapped_column(primary_key=True) + title: Mapped[str] = mapped_column(nullable=False, unique=True) + + url: Mapped[str] = mapped_column(nullable=False, unique=True) + content: Mapped[str] = mapped_column(type_=Text) + + @typing.override + def __str__(self): + return f"{self.id} {self.title}" diff --git a/blog/post/views.py b/blog/post/views.py index 2a882c7..fdc51bc 100644 --- a/blog/post/views.py +++ b/blog/post/views.py @@ -16,7 +16,7 @@ from blog.extensions import flask_sitemap from blog import cache, db -from blog.post.models import Post +from blog.post.models import Post, Icon from blog.category.models import Category post = Blueprint("postb", __name__) @@ -28,7 +28,11 @@ def decorated_function(*args, **kwargs): page_category = current_app.config["PAGE_CATEGORY"] pages_query = sa.select(Post).where(Post.category_id.in_(page_category)) pages = db.session.scalars(pages_query).all() - return f(pages=pages, *args, **kwargs) + + icons_query = sa.select(Icon) + icons = db.session.scalars(icons_query).all() + + return f(pages=pages, icons=icons, *args, **kwargs) return decorated_function diff --git a/blog/templates/footer.html b/blog/templates/footer.html index 1a60a8b..5d190af 100644 --- a/blog/templates/footer.html +++ b/blog/templates/footer.html @@ -2,21 +2,11 @@ diff --git a/migrations/versions/b0e3595603e9_add_icons_model.py b/migrations/versions/b0e3595603e9_add_icons_model.py new file mode 100644 index 0000000..a11a69e --- /dev/null +++ b/migrations/versions/b0e3595603e9_add_icons_model.py @@ -0,0 +1,38 @@ +"""Add icons model + +Revision ID: b0e3595603e9 +Revises: 49df8e610d33 +Create Date: 2025-07-25 03:43:25.175199 + +""" + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "b0e3595603e9" +down_revision = "49df8e610d33" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "icons", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("title", sa.String(), nullable=False), + sa.Column("url", sa.String(), nullable=False), + sa.Column("content", sa.Text(), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("title"), + sa.UniqueConstraint("url"), + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("icons") + # ### end Alembic commands ###