From 7c6fc025290bfa9e5435d41e5f4083e39ff122ed Mon Sep 17 00:00:00 2001 From: pi3c Date: Fri, 22 Sep 2023 14:31:42 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BA=D1=80=D0=B0=D1=82=D0=BA=D0=BE=D0=B5=20=D0=BE=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D0=BC=D0=B0=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B2=20=D0=B7=D0=B0=D0=B3=D0=BE=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=BA,=20=D0=BE=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B8=20=D1=82=D0=B5=D0=BA=D1=81=D1=82=20=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D1=82=D1=8C=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...n.py => 8c415e462cb3_initial_migration.py} | 13 +++-- pyproger/admin/views.py | 9 ++- pyproger/app.py | 4 ++ pyproger/blog/__init__.py | 0 pyproger/blog/blog.py | 9 +++ pyproger/blog/urls.py | 43 ++++++++++++++ pyproger/dbase/database.py | 24 ++++++++ pyproger/dbase/models.py | 7 ++- pyproger/templates/admin/edit.html | 2 + pyproger/templates/blog/base.html | 50 ++++++++++++++++ pyproger/templates/blog/index.html | 58 +++++++++++++++++++ pyproger/templates/blog/postview.html | 19 ++++++ pyproger/templates/site/index.html | 9 +++ 13 files changed, 237 insertions(+), 10 deletions(-) rename migrations/versions/{af05a1cbd975_initial_migration.py => 8c415e462cb3_initial_migration.py} (94%) create mode 100644 pyproger/blog/__init__.py create mode 100644 pyproger/blog/blog.py create mode 100644 pyproger/blog/urls.py create mode 100644 pyproger/dbase/database.py create mode 100644 pyproger/templates/blog/base.html create mode 100644 pyproger/templates/blog/index.html create mode 100644 pyproger/templates/blog/postview.html create mode 100755 pyproger/templates/site/index.html diff --git a/migrations/versions/af05a1cbd975_initial_migration.py b/migrations/versions/8c415e462cb3_initial_migration.py similarity index 94% rename from migrations/versions/af05a1cbd975_initial_migration.py rename to migrations/versions/8c415e462cb3_initial_migration.py index a124c4a..17969c9 100644 --- a/migrations/versions/af05a1cbd975_initial_migration.py +++ b/migrations/versions/8c415e462cb3_initial_migration.py @@ -1,8 +1,8 @@ """initial_migration -Revision ID: af05a1cbd975 +Revision ID: 8c415e462cb3 Revises: -Create Date: 2023-09-19 22:57:11.510132 +Create Date: 2023-09-22 12:19:22.923813 """ import flask_security @@ -10,7 +10,7 @@ import sqlalchemy as sa from alembic import op # revision identifiers, used by Alembic. -revision = "af05a1cbd975" +revision = "8c415e462cb3" down_revision = None branch_labels = None depends_on = None @@ -20,8 +20,8 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.create_table( "role", - sa.Column("id", sa.Integer(), nullable=False), sa.Column("name", sa.String(length=80), nullable=False), + sa.Column("id", sa.Integer(), nullable=False), sa.Column("description", sa.String(length=255), nullable=True), sa.Column("permissions", flask_security.datastore.AsaList(), nullable=True), sa.Column( @@ -78,8 +78,9 @@ def upgrade(): "post", sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), sa.Column("author", sa.Integer(), nullable=True), - sa.Column("slug", sa.String(length=30), nullable=False), - sa.Column("title", sa.String(length=50), nullable=False), + sa.Column("slug", sa.String(length=100), nullable=False), + sa.Column("title", sa.Text(), nullable=False), + sa.Column("description", sa.Text(), nullable=False), sa.Column("published", sa.Boolean(), nullable=True), sa.Column("create_datetime", sa.DateTime(), nullable=True), sa.Column("update_datetime", sa.DateTime(), nullable=True), diff --git a/pyproger/admin/views.py b/pyproger/admin/views.py index 06bc981..80a788e 100644 --- a/pyproger/admin/views.py +++ b/pyproger/admin/views.py @@ -1,4 +1,4 @@ -from flask import abort, redirect, request, url_for +from flask import abort, g, redirect, request, url_for from flask_admin.contrib import sqla from flask_ckeditor import CKEditorField from flask_security import current_user @@ -72,6 +72,7 @@ class PostView(MyAdminView): tags="Тэги", slug="Слаг", title="Заголовок", + description="Краткое описание статьи", author="Автор", published="Опубликовано", create_datetime="Дата создания", @@ -79,6 +80,10 @@ class PostView(MyAdminView): text="Текст", ) - form_overrides = dict(text=CKEditorField) + form_overrides = dict( + title=CKEditorField, + description=CKEditorField, + text=CKEditorField, + ) create_template = "admin/edit.html" edit_template = "admin/edit.html" diff --git a/pyproger/app.py b/pyproger/app.py index 862a023..5b576aa 100644 --- a/pyproger/app.py +++ b/pyproger/app.py @@ -76,6 +76,10 @@ def create_app(test_config=None): app.register_blueprint(bp_cli) + from pyproger.blog.blog import bp as bp_blog + + app.register_blueprint(bp_blog) + @security.context_processor def security_context_processor(): return dict( diff --git a/pyproger/blog/__init__.py b/pyproger/blog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyproger/blog/blog.py b/pyproger/blog/blog.py new file mode 100644 index 0000000..0efc94d --- /dev/null +++ b/pyproger/blog/blog.py @@ -0,0 +1,9 @@ +from flask import Blueprint + +bp = Blueprint( + "bp_blog", + __name__, + template_folder="templates/blog", +) + +from . import urls diff --git a/pyproger/blog/urls.py b/pyproger/blog/urls.py new file mode 100644 index 0000000..738bcd0 --- /dev/null +++ b/pyproger/blog/urls.py @@ -0,0 +1,43 @@ +import locale + +from flask import render_template, render_template_string, request + +from ..dbase.database import get_paginated_posts, get_post +from .blog import bp + +locale.setlocale(locale.LC_ALL, "") + + +@bp.route("/", methods=["GET"], defaults={"page": 1}) +@bp.route("/", methods=["GET"]) +def index(page=1): + per_page = 3 + posts, total_pages = get_paginated_posts(page, per_page) + list_pages = [ + x for x in range(1, total_pages + 1) if x >= page - 2 and x <= page + 2 + ] + return render_template( + "blog/index.html", + request=request, + posts=posts, + title="pyproger - разговоры про питон", + menu_title="pyproger", + page=page, + total_pages=total_pages, + list_pages=list_pages, + ) + + +@bp.route("/post/") +@bp.route("/post/") +def post(slug=None): + if slug: + current_post = get_post(slug) + return render_template( + "blog/postview.html", + title=f"pyproger - {current_post.Post.title}", + menu_title="pyproger", + post=current_post, + ) + else: + return render_template_string("noup") diff --git a/pyproger/dbase/database.py b/pyproger/dbase/database.py new file mode 100644 index 0000000..196b1e9 --- /dev/null +++ b/pyproger/dbase/database.py @@ -0,0 +1,24 @@ +from . import db +from .models import Post, User + + +def get_paginated_posts(page, per_page): + quer = ( + db.session.query(Post, User) + .join(User, Post.author == User.id) + .order_by(Post.create_datetime.desc()) + .paginate(page=page, per_page=per_page, error_out=False) + ) + total_pages = quer.total // per_page + [0, 1][quer.total % per_page != 0] + + return quer, total_pages + + +def get_post(slug): + post_query = ( + db.session.query(Post, User) + .join(User, Post.author == User.id) + .filter(Post.slug == slug) + .first() + ) + return post_query diff --git a/pyproger/dbase/models.py b/pyproger/dbase/models.py index e317e02..adf56eb 100644 --- a/pyproger/dbase/models.py +++ b/pyproger/dbase/models.py @@ -1,5 +1,6 @@ import datetime +from flask_security import current_user from flask_security.models import fsqla from sqlalchemy import Boolean, Column, DateTime, Integer, String, Text @@ -69,8 +70,9 @@ class Post(db.Model): autoincrement=True, ) author = Column(Integer, db.ForeignKey("user.id")) - slug = Column(String(30), nullable=False) - title = Column(String(50), nullable=False) + slug = Column(String(100), nullable=False) + title = Column(Text, nullable=False) + description = Column(Text, nullable=False) published = Column(Boolean, default=False) tags = db.relationship("Tag", secondary=tag_post) @@ -82,5 +84,6 @@ class Post(db.Model): update_datetime = Column( DateTime(), nullable=True, + onupdate=datetime.datetime.utcnow(), ) text = Column(Text) diff --git a/pyproger/templates/admin/edit.html b/pyproger/templates/admin/edit.html index 8332710..a740e1c 100644 --- a/pyproger/templates/admin/edit.html +++ b/pyproger/templates/admin/edit.html @@ -8,5 +8,7 @@ if you have set the configuration variables more than CKEDITOR_SERVE_LOCAL and C or you need to config the CKEditor textarea, use the line below to register the configuration. The name value should be the name of the CKEditor form field. #} +{{ ckeditor.config(name='Title') }} + {{ ckeditor.config(name='Text') }} {% endblock %} diff --git a/pyproger/templates/blog/base.html b/pyproger/templates/blog/base.html new file mode 100644 index 0000000..d0d435c --- /dev/null +++ b/pyproger/templates/blog/base.html @@ -0,0 +1,50 @@ + + + + + + + + {% block title %} + {% endblock title %} + + + + + +
+ + + +
+ {% block content %} {% endblock %} +
+
+ + + + + + + diff --git a/pyproger/templates/blog/index.html b/pyproger/templates/blog/index.html new file mode 100644 index 0000000..0de2d79 --- /dev/null +++ b/pyproger/templates/blog/index.html @@ -0,0 +1,58 @@ +{% extends 'blog/base.html' %} + +{% block title %} + {{title}} +{% endblock %} + +{% block menu_title %} + {{ menu_title }} +{% endblock %} + +{% block content %} +
+
+
+ +
+
+ + {% for p in posts %} + +
{{ p.Post.title | safe }}
+ {{ p.Post.description | safe}} +
+ + Опубликовал + + {{ p.User.username}} + + {{ p.Post.create_datetime.strftime('%d %B, %Y') }} + +
+ {% endfor %} +
+ + +{% endblock %} diff --git a/pyproger/templates/blog/postview.html b/pyproger/templates/blog/postview.html new file mode 100644 index 0000000..f1e098b --- /dev/null +++ b/pyproger/templates/blog/postview.html @@ -0,0 +1,19 @@ +{% extends 'blog/base.html' %} + +{% block title %} +{{title}} +{% endblock %} + +{% block menu_title %} +{{ menu_title }} +{% endblock %} + +{% block content %} + +
+
+

{{ post.Post.title | safe }}

+ {{ post.Post.text | safe }} +
+ +{% endblock %} diff --git a/pyproger/templates/site/index.html b/pyproger/templates/site/index.html new file mode 100755 index 0000000..ef60fdd --- /dev/null +++ b/pyproger/templates/site/index.html @@ -0,0 +1,9 @@ + + + +
+ админ панель +
+ + +