From bdcc7612dd4d568ef78edec096a02032d178ba20 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Wed, 22 Oct 2025 17:59:25 +0300 Subject: [PATCH 1/6] [2025.10] chore: move and reorganize mermaid model assets Moved model `.mmd` files under the `static/mermaid` directory, and SVG assets under `static/img` to improve project structure. --- {mermaid => assets/img}/models.mmd.png | Bin {mermaid => assets/img}/models.mmd.svg | 0 {mermaid => assets/mermaid}/models.mmd | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {mermaid => assets/img}/models.mmd.png (100%) rename {mermaid => assets/img}/models.mmd.svg (100%) rename {mermaid => assets/mermaid}/models.mmd (100%) diff --git a/mermaid/models.mmd.png b/assets/img/models.mmd.png similarity index 100% rename from mermaid/models.mmd.png rename to assets/img/models.mmd.png diff --git a/mermaid/models.mmd.svg b/assets/img/models.mmd.svg similarity index 100% rename from mermaid/models.mmd.svg rename to assets/img/models.mmd.svg diff --git a/mermaid/models.mmd b/assets/mermaid/models.mmd similarity index 100% rename from mermaid/models.mmd rename to assets/mermaid/models.mmd From c1fd869880117559048ff0653ab4efa9cb47267e Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Wed, 22 Oct 2025 18:03:30 +0300 Subject: [PATCH 2/6] [2025.10] build: add .editorconfig for project-wide config rules Introduced a `.editorconfig` file to enforce consistent coding styles across different editors and IDEs. Includes settings for general files, Markdown, and Mermaid-specific formatting preferences. --- .editorconfig | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..745bbd5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,70 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 79 +tab_width = 4 +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = true +ij_smart_tabs = false +ij_visual_guides = +ij_wrap_on_typing = false + +[{*.markdown,*.md}] +ij_markdown_force_one_space_after_blockquote_symbol = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_between_words = true +ij_markdown_format_tables = true +ij_markdown_insert_quote_arrows_on_wrap = true +ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_keep_line_breaks_inside_text_blocks = true +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_between_paragraphs = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_between_paragraphs = 1 +ij_markdown_wrap_text_if_long = true +ij_markdown_wrap_text_inside_blockquotes = true + +[{*.mermaid,*.mmd}] +ij_mermaid_after_arrow_text_within_sep = false +ij_mermaid_after_colon = true +ij_mermaid_after_comma = true +ij_mermaid_around_arrow = true +ij_mermaid_around_equality = false +ij_mermaid_around_inline_arrow_text = true +ij_mermaid_around_style_separator = false +ij_mermaid_beetween_line_type_and_relation_type = false +ij_mermaid_before_arrow_text_within_sep = false +ij_mermaid_before_colon = false +ij_mermaid_before_comma = false +ij_mermaid_before_generic = false +ij_mermaid_before_open_curly = true +ij_mermaid_before_open_round = false +ij_mermaid_before_semicolon = false +ij_mermaid_between_node_id_and_node_shape = false +ij_mermaid_between_state_and_annotation = true +ij_mermaid_force_one_space_between_words = true +ij_mermaid_keep_indents_on_empty_lines = false +ij_mermaid_keep_lines_around_structured_statements = 1 +ij_mermaid_keep_lines_between_other_statements = 0 +ij_mermaid_keep_lines_between_structured_statements = 1 +ij_mermaid_keep_lines_within_structures = 0 +ij_mermaid_min_lines_around_structured_statements = 0 +ij_mermaid_min_lines_between_other_statements = 0 +ij_mermaid_min_lines_between_structured_statements = 0 +ij_mermaid_min_lines_within_structures = 0 +ij_mermaid_within_annotation_braces = false +ij_mermaid_within_arrow_text_sep = false +ij_mermaid_within_curly = true +ij_mermaid_within_node_shapes = false +ij_mermaid_within_round = false +ij_mermaid_within_square = false From 97d8cf2e02866248636677f2e370698105066947 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Wed, 22 Oct 2025 18:53:22 +0300 Subject: [PATCH 3/6] [2025.10] docs: migrate project specification to Markdown format Replaced outdated `.rst` files with `.md` equivalents for improved readability and compatibility. Includes updated links, layout, and Mermaid diagram integrations for enhanced documentation clarity. --- README.md | 23 +++ README.rst | 31 ---- index.md | 468 ++++++++++++++++++++++++++++++++++++++++++++++++ index.rst | 513 ----------------------------------------------------- 4 files changed, 491 insertions(+), 544 deletions(-) create mode 100644 README.md delete mode 100644 README.rst create mode 100644 index.md delete mode 100644 index.rst diff --git a/README.md b/README.md new file mode 100644 index 0000000..0f530e2 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Blog Site Specification + +This repository contains the specification for the Blog Site project, +intended for educational purposes. + +## Project Description + +The project aims to develop a robust and user-friendly web application using +the Django framework. The primary goal is to create a blogging platform that +allows users to publish and manage articles on various topics. The application +will provide an intuitive interface for authors to compose and format their +articles, while also offering a seamless reading experience for visitors. + +## Repository Structure + +This repository contains only the project specification and related documents, +such as UML diagrams, data fixtures etc. No actual code implementation here. +Anyone can refer to this documentation to understand the project requirements +and design before starting the implementation phase. + +## Documents + +- [Blog Site Specification](./index.md) diff --git a/README.rst b/README.rst deleted file mode 100644 index 1555e02..0000000 --- a/README.rst +++ /dev/null @@ -1,31 +0,0 @@ -############################################################################### - Blog Site Specification -############################################################################### - -This repository contains the specification for the Blog Site project, -intended for educational purposes. - -Project Description -=================== - -The project aims to develop a robust and user-friendly web application using -the Django framework. The primary objective is to create a blogging platform -that allows users to publish and manage articles on various topics. -The application will provide an intuitive interface for authors to compose -and format their articles, while also offering a seamless reading experience -for visitors. - -Repository Structure -==================== - -This repository contains only the project specification and related documents, -such as UML diagrams, data fixtures etc. No actual code implementation here. -Anyone can refer this documentation to understand the project requirements and -design before starting the implementation phase. - -Documents -========= - -- `Blog Site Specification`_ - -.. _Blog Site Specification: ./index.rst diff --git a/index.md b/index.md new file mode 100644 index 0000000..f9d2dbb --- /dev/null +++ b/index.md @@ -0,0 +1,468 @@ +# Blog Site + +The project aims to develop a robust and user-friendly web application using +the Django framework. The primary objective is to create a blogging platform +that allows users to publish and manage articles on various topics. +The application will provide an intuitive interface for authors to compose and +format their articles, while also offering a seamless reading experience for +visitors. + +## Key Features + +### User Registration and Authentication + +The application will provide user registration and authentication +functionality, allowing individuals to create accounts, log in, and manage +their profile information. This feature will enable authors to have +personalized accounts and maintain ownership of their published articles. + +### Article Management + +Authors will be able to create, edit, and delete articles within the +application. The system will offer a user-friendly editor. Additionally, +authors will be able to categorize articles by assigning relevant topics to +them. + +### Topic Subscription + +The application will include a subscription feature that allows users to +subscribe to topics of interest. By subscribing to specific topics, users will +receive notifications or updates whenever new articles are published in those +categories. This feature will enhance user engagement and ensure that readers +stay informed about the topics they find most valuable. + +Overall, the project aims to deliver an efficient blogging platform that caters +to both authors and readers. By providing a seamless user experience and +incorporating essential functionalities such as user authentication, article +management, and topic subscriptions, the application will empower users to +create, share, and explore engaging content within a well-structured and +organized platform. + +Here is a starter repository template, that may help: +[Starter template](https://github.com/devsforge/django-tpl.git). + +## Challenge: Functional views + +It's ok not to return **actual** content for now. Just ensure all the +routes are available and provide correct data. Use anything you like to +return within an HTTP response. + +- `/about/`: Provides a regular text for a user, describing the + functionalities of the django site. +- `/`: A site's homepage. This will contain a list of blogs published + via the django site. +- `/
/`: A single article detail view. The URL contains a dynamic part + in it. This will be used to fetch a single article from the database. +- `/
/comment/`: This view will be used to add comments to an article. +- `/create/`: A article creation form. +- `/
/update/`: A view to update existing article data. +- `/
/delete/`: A view to confirm article deletion. +- `/topics/`: A list of topics available on the site. +- `/topics//add/`: Add the selected topic to the preferred topics list. +- `/topics//remove/`: Removes the selected topic from preferred. +- `/topics//subscribe/`: A view to subscribe for a topic. +- `/topics//unsubscribe/`: A view to unsubscribe from a topic. +- `/profile//`: A site user's personal page. +- `/set-password/`: This route will be used to change users' credential data. +- `/set-userdata/`: This route will be user to change users' data. +- `/deactivate/`: Account deactivation (deletion) view. +- `/register/`: This view contains a user registration form. +- `/login/`: This view contains a login form. +- `/logout/`: Logout page. This view should redirect the user back to the + homepage. + +> [!WARNING] +> Optional task(s) +> +> - `/archive///`: This view provides a list of articles + published on a specified month of a specified year. This view should apply + date validation and raise `Http404` for invalid paths. The valid date is a + year's 4-digits form followed by one or two digits representing a month. + Month range should be limited as [1..12], leading zero may be omitted. + Valid URLs are: +> +> /archive/2023/1/ +> /archive/2023/01/ +> /archive/2023/10/ +> + +## Challenge: Data models + +> [!TIP] +> Django admin may be used to create some fake data. To gather access to +> an admin section, you need to create a superuser. The easiest way to do that +> is to use a django command: +> +> ``` shell +> python manage.py createsuperuser +> ``` + +**General** + +- Each model will be registered for the admin site. + +**Article topic** + +- This is a simple model, that contains information about topic: + - topic title (unique value, 64 characters or fewer) + - topic short description (255 characters or fewer) + +**Article** + +- Article requires title (255 characters or fewer). +- Article requires content (at least 255 characters). +- Creation date should be autogenerated at article creation and would + never be updated. +- Updated date will be updated at each article save. + +**Article comment** + +- Comment requires creation date (autogenerated). +- Comment requires message text. + +**Relationships** + +> [!NOTE] +> The standard Django user model **will be** used for now. To apply model +> reference pass `"auth.User"` as a related model. Users can be created via +> admin page. You can also refer to the same model as shown below: +> +> ``` python +> from django.contrib.auth import get_user_model +> from django.conf import settings +> +> UserModel = get_user_model() # option 1 +> UserModel = settings.AUTH_USER_MODEL # option 2 +> UserModel = "auth.User" # option 3 +> ``` + +- `article` and `topics` have *many-to-many* relationship. +- `article` and `user` have *one-to-many* relationship. An article can have * + *only one** author, but users can create as many articles as they want. +- `article` and `comment` have *one-to-many* relationship. An article may be a + container for many comments, but a comment is related to a single article. +- `comment` and `user` have *one-to-many* relationship. It's similar to the + *article-user* relationship. +- `topic` and `user` use *many-to-many* relationship. A single user can prefer + none or as many topics as needed and vice versa. This relationship represents + topics preferred by a certain blog user. Also this provides an additional + option to mark some of the preferred topics with a **notify** flag to receive + newsletters about specified topics updates. The difference between *prefer* + and *notify* is that *preferred* topics affect the article list for a user, + and *notify* is responsible for newsletters for the user. + +**UML diagram** + +```mermaid +erDiagram + + topic { + string title + string description + } + + article { + string title + text content + date created_at + date updated_at + } + + comment { + datetime created_at + text message + } + + article ||--|{ comment: contains + topic }|--o{ article: contains + topic }o--o{ user: prefers + user }|--|| article: author + user }|--|| comment: author + +``` + +## Challenge: ORM + +Update existing views to represent entities that are actually stored inside the +project's database. + +- `/`: should represent a list of existing articles. +- `/
/`: should represent a single existing article. +- Detail view should get a list of article-related comments. +- `/profile//`: should contain information about user and a list + of articles authored by this user. +- All views related to a single entity (*detail*, *update*, *delete*, + *profile*) should raise `Http404` in case entity could not be fetched. + +> [!TIP] +> It's common to store dedicated functions/classes that supports some specific +> business logic in a separate module called `services.py` or `utils.py` within +> an application directory. + +> [!WARNING] +> Optional task(s) +> +> - Create a service to fetch articles ordered by specified user preferences. + This means, topics preferred by a user affect articles order. Queryset + should be ordered in a way, to have articles with most corresponding topics + at the begging. + +## Challenge: Templates + +> [!HINT] +> Helpful link: +> [Bootstrap template](https://github.com/devsforge/css-bootstrap-blog) + +> [!IMPORTANT] +> Links related to user data **may be** placeholders for now. + +**General** + +- **All** templates should be inherited from the `base.html` template. +- Each page has a descriptive title HTML tag, which included `| Blog` + suffix, e.g. "Articles | Blogs," "Sample | Blog," "Login | Blog" etc. +- Each page should contain a link to homepage (`/` URL route). +- Each page contains a list of registered topics. Each view of this kind + filters only articles of a relevant topic. This should be implemented + with a custom template context processor. +- Replace content block for *about* page with some static content. +- Application-level templates should be located within appropriate + applications. + +> [!WARNING] +> Optional task(s) +> +> - Each page should contain a list of links to archive views for the last year. +> - Each page should contain an inclusion-block(s) with following links: +> - `/registration/`: new user registration form +> - `/login/`: user login form +> - `/create/`: article creation page + +**Articles list** + +- The main page contains a list of published articles. +- Each article entity is rendered using a custom template tag. +- `article` template tag renders information about a article object: + - article title + - article content (trimmed to \~50 characters) + - article creation date + - related topics (3 topics or fewer) + - number of related comments + +**Article details** + +> [!IMPORTANT] +> Article update and deletion views **would not** affect data for now. + +- A article detail page contains links to **update** or **delete** + current article. +- Page provides information about the article: + - Article title + - Creation date + - Author name + - Related topics + - Article content +- Page contains a list of related comments. +- Each comment contains: + - Author name + - Comment creation time + - Comment message + +**Profile page** + +- Author page contains information about the author: + - First name + - Last name + + Add more information, if needed. + +- Author page contains a list of articles created by this author. + +- Author page contains buttons/links to change user data and password or + deactivate a user's account. + +**Forms** + +> [!IMPORTANT] +> There is **no need** to add actual forms now. They will be generated by +> Django. This section describes the final view of these pages. It's ok just to +> create a dedicated template for future use. + +- `/register/` page contains a new user registration form. It should + take inputs from the user: + - username + - email + - password + - confirm password +- `/login/` page contains a user login form. It should take the inputs from the + user: + - username + - password +- `/create/` and `/
/update/` pages contain a form to collect an + article's data: + - title + - relevant topics + - content +- `/
/delete` page contains a simple delete confirmation form. +- Change password form has two fields: + - new password + - confirm password +- Change user's data form collects all information, that can be changed, e.g. + `username`, `first name`, `last name` etc. +- User preferences page contains a list of available topics. Users can mark + some topics as preferred. Also, for preferred topics an option to *subscribe* + for the newsletters becomes available. + +## Challenge: Articles' slugs + +> [!WARNING] +> This is an optional challenge in addition to: +> +> - [Challenge: Functional views](#challenge-functional-views) +> - [Challenge: Templates](#challenge-templates) +> - [Challenge: Data models](#challenge-data-models) +> - [Challenge: ORM](#challenge-orm) + +- Update `Article` model with `slug` field. The slug value is: + - required for each article + - unique for each article +- Create a data migration to provide slugs for existing articles. +- `slug` should be auto-generated on article save. The pattern is + `article.title-article.created_date`, e.g. "Sample article" created + at "03/24/2023" should receive slug: `sample-article-2023-03-24`. +- Update the detail view URL path with the article slug as a dynamic portion. + +## Challenge: Auth forms + +- Create a form for new users registration with required fields: + - `username` + - `email` + - `password` + - `confirm password` +- `username` value should be validated against existing values. +- `password` and `confirm password` values should match. +- Create a form to log in a user. +- Validation errors are to be rendered on the template. + +## Challenge: Authentication + +- For anonymous users `/register/` and `/login/` links should be visible + in navbar. +- For authenticated users `/logout/` and `/create/` links should be + visible in navbar. +- If an authenticated user is admin or stuff, they should see a link to + the admin page. +- `/register/`: Users should provide all required information about + them: desired username and email. Name data (both first and last) is + optional. After user creation they should be redirected to login page + to perform an authentication process. Invalid form should provide + information about error(s). +- `/login/`: Users should provide their credentials to login. In case + login is successful they should be redirected to their profile (if no + `?next=url` query string available). +- `/create/`: Only authenticated users should be able to visit this + page. In case an anonymous user is trying to request this view, they + should be redirected to the login view first, and after successful + authentication get back to article creation. Then an article is + created, it should be authored by the currently authenticated user. +- `/
/comment/`: Currently authenticated user should be + referenced as a comment's author. +- Articles may be modified or deleted only by their authors from the + detail article page. However, admins can still perform articles + actions from the admin page. +- User-related paths are restricted for non-authorized users. + - `/set-password/` + - `/set-userdata/` +- `POST` request `/deactivate/` should mark current authenticated user + as *deleted* and log them user. +- Authenticated users should be able to adjust their preferred topics + lists. +- Authenticated users should be able to **subscribe** or **unsubscribe** + for a selected topic. + +> [!WARNING] +> Optional task(s) +> +> - Adjust the order of an article list according to authenticated user + preferences. For anonymous users keep the default ordering. +> - Implement account reactivation behavior. The exact workflow does not + matter. The sample scenario is to collect email for the user and check it + for existing in the database. After that create a request for admin to + activate an account and send a confirmation email, when all is done. + +## Challenge: Article related forms + +- Implement an article creation form. This form will be used to create new + articles and to update existing ones. +- Each created article should have at least one related topic. +- Implement a comment form to gather a comment from a user. +- Only `POST` requests to `/
/comment/` are allowed from this + moment. +- Implement functionality: + - article creation + - article update + - article comment (create a related comment) + - article deletion +- Only authenticated users can create articles. +- Article can be edited only by its author. +- Article can be deleted only by its author. +- Only authenticated users can comment on articles. + +## Challenge: Class-Based Views + +- Replace **all** existing views via `CBV`. +- Existing functionality should not be corrupted. + +> [!NOTE] +> It's ok to use built-in Django CBV if needed. + +## Challenge: Serializers + +**Article topic** + +- Topic serializer is for read-only purposes only. Topics can be created + via the admin page only. +- Serialized data should contain all available data, e.g. `pk`, `title`, + `description`. + +**Article comment** + +- article comment serializer can perform both reading and writing + operations. But it can't be used to *update* or *delete* comment. +- Random, or pre-defined user may be used as comment's author for now. + This will be fixed in the future. + +**Article** + +- article serializer provides full access to articles. All operations + are available: list, retrieve, create, update, and destroy. + +**User** + +- User serializer provides full access to site users' data. All + operations are available for now: list, retrieve, create, update, and + destroy. This behavior will be fixed in the future to prevent + unauthorized data modifications. + +## Challenge: API views + +All blog-site functionality is to be mirrored via REST API. + +> [!NOTE] +> It's ok to pass *pre-defined* user as argument in request's body. +> This will be fixed in the next challenge. + +## Challenge: Authentication and Permissions + +- Implement authentication system for REST API. + - For non-authenticated users it is possible to create a new account + - For non-authenticated users it is possible to collect authentication + data. +- Access to user data is restricted. Authorized users can manipulate + only their own data (e.g. `retrieve`, `update`). +- Admins can retrieve all user's data (`list`), but can't change them + via REST API. However, it is still possible via the admin page. +- Authorized users can `create` articles or `update` and `delete` + articles created by them. +- Authorized users can add comments to a specified article. +- Authorized users can adjust their topic preferences. diff --git a/index.rst b/index.rst deleted file mode 100644 index acdc6ed..0000000 --- a/index.rst +++ /dev/null @@ -1,513 +0,0 @@ -.. - the specification for a training blog project (Django framework) - -.. _Starter template: - https://github.com/edu-python-course/django-template -.. _Bootstrap template: - https://github.com/edu-python-course/blog-bootstrap - -Blog Site -========= - -The project aims to develop a robust and user-friendly web application using -the Django framework. The primary objective is to create a blogging platform -that allows users to publish and manage articles on various topics. -The application will provide an intuitive interface for authors to compose -and format their articles, while also offering a seamless reading experience -for visitors. - -**Key Features** - -.. rubric:: User Registration and Authentication - -The application will provide user registration and authentication -functionality, allowing individuals to create accounts, log in, and -manage their profile information. This feature will enable authors -to have personalized accounts and maintain ownership of their published -articles. - -.. rubric:: Article Management - -Authors will have the ability to create, edit, and delete articles within -the application. The system will offer a user-friendly editor. -Additionally, authors will be able to categorize articles by assigning -relevant topics to them. - -.. rubric:: Topic Subscription: - -The application will include a subscription feature that allows users -to subscribe to topics of interest. By subscribing to specific topics, -users will receive notifications or updates whenever new articles are -published in those categories. This feature will enhance user engagement -and ensure that readers stay informed about the topics they find most -valuable. - -Overall, the project aims to deliver an efficient blogging platform that -caters to both authors and readers. By providing a seamless user experience -and incorporating essential functionalities such as user authentication, -article management, and topic subscriptions, the application will empower -users to create, share, and explore engaging content within a well-structured -and organized platform. - -Here is a starter repository template, that may helps: `Starter template`_. - -Challenge: Functional views ---------------------------- - -It's ok not to return **actual** content for now. Just ensure all the -routes are available and provide correct data. Use anything you like to -return within HTTP response. - -- ``/about/``: Provides a regular text for a user, describing the - functionalities of the django site. -- ``/``: A site's homepage. This will contain a list of blogs - published via the django site. -- ``/
/``: A single article detail view. The URL contains - dynamic part in it. This will be used to fetch a single article from - the database. -- ``/
/comment/``: This view will be used to add comments to a - article. -- ``/create/``: A article creation form. -- ``/
/update/``: A view to update an existing article data. -- ``/
/delete/``: A view to confirm article deletion. -- ``/topics/``: A list of topics available on the site. -- ``/topics//add/``: Add the selected topic to preferred topics list. -- ``/topics//remove/``: Removes the selected topic from preferred. -- ``/topics//subscribe/``: A view to subscribe for a topic. -- ``/topics//unsubscribe/``: A view to unsubscribe from a topic. -- ``/profile//``: A site user's personal page. -- ``/set-password/``: This route will be used to change users' - credential data. -- ``/set-userdata/``: This route will be user to change users' data. -- ``/deactivate/``: Account deactivation (deletion) view. -- ``/register/``: This view contains a user registration form. -- ``/login/``: This view contains a login form. -- ``/logout/``: Logout page. This view should redirect user back to - homepage. - -.. warning:: - Optional task(s) - - - ``/archive///``: - This view provides a list of articles published on a specified month - of a specified year. This view should apply date validation and raise - ``Http404`` for invalid paths. The valid date is a year's 4-digits form - followed by 1 or 2 digits representing month. Month range should be - limited as [1..12], leading zero may be omitted. Valid URLs are: - - :: - - /archive/2023/1/ - /archive/2023/01/ - /archive/2023/10/ - -Challenge: Data models ----------------------- - -.. hint:: - Django admin may be used to create some dummy data. To gather access to - admin section you need to create a superuser. The easiest way to do that - is to use a django command: - - .. code-block:: shell - - python manage.py createsuperuser - -.. rubric:: General - -- Each model will be registered for admin site. - -.. rubric:: Article topic - -- This is a simple model, that contains information about topic: - - - topic title (unique value, 64 characters or fewer) - - topic short description (255 characters or fewer) - -.. rubric:: Article - -- Article requires title (255 characters or fewer). -- Article requires content (at least 255 characters). -- Creation date should be autogenerated at article creation, and would - never be updated. -- Updated date will be update at each article save. - -.. rubric:: Article comment - -- Comment requires creation date (autogenerated). -- Comment requires message text. - -.. rubric:: Relationships - -.. note:: - Standard Django user model **will be** used for now. To apply model - reference pass ``"auth.User"`` as related model. Users can be created - via admin page. You can also refer the same model as shown below: - - .. code-block:: python - - from django.contrib.auth import get_user_model - from django.conf import settings - - UserModel = get_user_model # option 1 - UserModel = settings.AUTH_USER_MODEL # option 2 - UserModel = "auth.User" # option 3 - -- ``article`` and ``topics`` have *many-to-many* relationship. -- ``article`` and ``user`` have *one-to-many* relationship. A article - can have **only one** author, but users can create as many articles as they - want. -- ``article`` and ``comment`` have *one-to-many* relationship. A article - may be a container for many comments, but a comment is related to a single - article. -- ``comment`` and ``user`` have *one-to-many* relationship. It's similar to - *article - user* relationship. -- ``topic`` and ``user`` use *many-to-many* relationship. A single user can - prefer none or as many topics as needed and vice versa. - This relationship represents topics preferred by a certain blog user. - Also this provides an additional option to mark some of preferred topics - with a **notify** flag, to receive newsletters about specified topics - updates. - The difference between *prefer* and *notify* is that *preferred* topics - affect the articles list for a user, and *notify* is responsible for - newsletters for the user. - -.. rubric:: UML diagram - -.. only:: html - - .. mermaid:: mermaid/models.mmd - :align: center - -.. only:: latex - - .. figure:: mermaid/models.mmd.png - :align: center - -Challenge: ORM --------------- - -Update existing views to represent entities that are actually stored -inside the project's database. - -- ``/``: should represent a list of existing articles. -- ``/
/``: should represent a single existing article. -- Detail view should obtain a list of article related comments. -- ``/profile//``: should contain information about user and a - list of articles authored by this user. -- All views related to a single entity (*detail*, *update*, *delete*, - *profile*) should raise ``Http404`` in case entity could not be - fetched. - -.. hint:: - It's common to store dedicated functions/classes that supports some - specific business logic in a separate module called ``services.py`` or - ``utils.py`` within an application directory. - -.. warning:: - Optional task(s) - - - Create a service to fetch articles, ordered by a specified user - preferences. This means, topics preferred by a user affects articles - orders. Queryset should be ordered in way, to have articles with most - corresponding topics at the begging. - -Challenge: Templates --------------------- - -.. hint:: - Helpful link: `Bootstrap template`_ - -.. important:: - Links related to user data **may be** placeholders for now. - -.. rubric:: General - -- **All** templates should be inherited from the ``base.html`` template. -- Each page has a descriptive title HTML tag, which included ``| Blog`` - suffix, e.g. "Articles | Blogs", "Sample | Blog", "Login | Blog" etc. -- Each page should contain a link to homepage (``/`` URL route). -- Each page contains a list of registered topics. Each view of this kind - filters only articles of a relevant topic. This should be implemented - with a custom template context processor. -- Replace content block for *about* page with some static content. -- Application-level templates should be located within appropriate - applications. - -.. warning:: - Optional task(s) - - - Each page should contain a list of links to archive views for the - last year. - - Each page should contain an inclusion-block(s) with following links: - - - ``/registration/``: new user registration form - - ``/login/``: user login form - - ``/create/``: article creation page - -.. rubric:: Articles list - -- Main page contains a list of published articles. -- Each article entity is rendered using a custom template tag. -- ``article`` template tag renders information about a article object: - - - article title - - article content (trimmed to ~50 characters) - - article creation date - - related topics (3 topics or fewer) - - number of related comments - -.. todo: - Include a block with most commented articles in user's preferred topics, - up to 3 articles. This require additional service/util implementation. - -.. rubric:: Article details - -.. important:: - Article update and deletion views **would not** affect data for now. - -- A article detail page contains links to **update** or **delete** - current article. -- Page provides information about article: - - - Article title - - Creation date - - Author name - - Related topics - - Article content - -- Page contains a list of related comments. -- Each comment contains: - - - Author name - - Comment creation time - - Comment message - -.. rubric:: Profile page - -- Author page contains information about author: - - - First name - - Last name - - Add more information, if needed. - -- Author page contains a list of articles created by this author. -- Author page contains buttons/links to change user data and password - or deactivate a user's account. - -.. rubric:: Forms - -.. important:: - There is **no need** to add actual forms now. They will be generated - by Django. This section describes the final view of these pages. - It's ok just to create a dedicated templates for future use. - -- ``/register/`` page contains a new user registration form. It should take - inputs from the user: - - - username - - email - - password - - confirm password - -- ``/login/`` page contains a user login form. It should take the inputs - from the user: - - - username - - password - -- ``/create/`` and ``/
/update/`` pages contain a form to collect - a article's data: - - - title - - relevant topics - - content - -- ``/
/delete`` page contains a simple delete confirmation form. -- Change password form has two fields: - - - new password - - confirm password - -- Change user's data form collects all information, that can be changed, - e.g. ``username``, ``first name``, ``last name`` etc. -- User preferences page contains a list of available topics. User can - mark some topics as preferred. Also for preferred topics an option - to *subscribe* for the newsletters becomes available. - -Challenge: Articles' slugs --------------------------- - -.. warning:: - This is an optional challenge in addition to: - - - `Challenge: Functional views`_ - - `Challenge: Templates`_ - - `Challenge: Data models`_ - - `Challenge: ORM`_ - -- Update ``Article`` model with ``slug`` field. The slug value is: - - - required for each article - - unique for each article - -- Create a data migration to provide slugs for existing articles. -- ``slug`` should be auto-generated on article save. - The pattern is ``article.title-article.created_date``, - e.g. "Sample article" created at "03/24/2023" should receive slug: - ``sample-article-2023-03-24``. -- Update detail view URL path with article slug as dynamic portion. - -Challenge: Auth forms ---------------------- - -- Create form for new users registration with required fields: - - - ``username`` - - ``email`` - - ``password`` - - ``confirm password`` - -- ``username`` value should be validated against existing values. -- ``password`` and ``confirm password`` values should match. -- Create form for existing users login. -- Validations errors are to be rendered on the template. - -Challenge: Authentication -------------------------- - -- For anonymous users ``/register/`` and ``/login/`` links should be - visible in navbar. -- For authenticated users ``/logout/`` and ``/create/`` links should be - visible in navbar. -- If authenticated user is admin or stuff they should see a link to - admin page. -- ``/register/``: Users should provide all required information about - them: desired username and email. Name data (both first and last) is - optional. After user creation they should be redirected to login page - to perform authentication process. Invalid form should provide - information about error(s). -- ``/login/``: Users should provide their credentials to login. In case - login is successful they should be redirected to their profile (if no - ``?next=url`` query string available). -- ``/create/``: Only authenticated users should be able to visit this - page. In case anonymous user is trying to request this view they - should be redirected to the login view first, and after successful - authentication get back to article creation. Then a article is created, it - should be authored by the currently authenticated user. -- ``/
/comment/``: Currently authenticated user should be - referenced as a comment's author. -- Articles may be modified or deleted only by their authors from the detail - article page. However, admins can still performs articles actions from - the admin page. -- User related paths are restricted for non-authorized users. - - - ``/set-password/`` - - ``/set-userdata/`` - -- ``POST`` request ``/deactivate/`` should mark current authenticated user as - *deleted* and log them user. -- Authenticated users should be able to adjust their preferred topics lists. -- Authenticated users should be able to **subscribe** or **unsubscribe** for - a selected topic. - -.. warning:: - Optional task(s) - - - Adjust the order of article list according to authenticated user - preferences. For anonymous users keep default ordering. - - Implement account reactivation behavior. The exact workflow does not - mater. The sample scenario is to collect email for the user and check - it for existing in the database. After that create a request for admin - to activate an account and send a confirmation email, when all is done. - -Challenge: Article related forms --------------------------------- - -- Implement a article form. This form will be used to create new articles - and to update existing ones. -- Each created article should have at least one related topic. -- Implement a comment form to gather a comment from a user. -- Only ``POST`` requests to ``/
/comment/`` are allowed from this - moment. -- Implement functionality: - - - article creation - - article update - - article comment (create a related comment) - - article deletion - -- Only authenticated users can create articles. -- Article can be edited only by its author. -- Article can be deleted only by its author. -- Only authenticated users can comment articles. - -.. todo: - Add admin site challenge: customize admin site view, forms etc. - Apply admin permissions and restrictions for the admin site. - -Challenge: Class-Based Views ----------------------------- - -- Replace **all** existing views via ``CBV``. -- Existing functionality should not be corrupted. - -.. note:: - It's ok to use built-in Django CBV if needed. - -Challenge: Serializers ----------------------- - -.. rubric:: Article topic - -- Topic serializer is for read-only purposes only. Topics can be created - via admin page only. -- Serialized data should contain all available data, e.g. ``pk``, ``title``, - ``description``. - -.. rubric:: Article comment - -- article comment serializer can perform both reading and writing - operations. But it can't be used to *update* or *delete* comment. -- Random, or pre-defined user may be used as comment's author for now. - This will be fixed in the future. - -.. rubric:: Article - -- article serializer provides full access to articles. All operations - are available: list, retrieve, create, update and destroy. - -.. rubric:: User - -- User serializer provides full access to site users data. All operations - are available for now: list, retrieve, create, update and destroy. - This behavior will be fixed in the future, to prevent unauthorized data - modifications. - -Challenge: API views --------------------- - -All blog-site functionality are to be mirrored via REST API. - -.. note:: - It's ok to pass *pre-defined* user as argument in request's body. - This will be fixed in the next challenge. - -Challenge: Authentication and Permissions ------------------------------------------ - -- Implement authentication system for REST API. - - - For non-authenticated users it is possible to create a new account - - For non-authenticated users it is possible to obtain authentication - data. - -- Access to user data is restricted. Authorized users can manipulate - only their own data (e.g. ``retrieve``, ``update``). -- Admins can retrieve all users data (``list``), but can't change them - via REST API. However, it is still possible via admin page. -- Authorized users can ``create`` articles or ``update`` and ``delete`` - articles created by them. -- Authorized users can add comments to a specified article. -- Authorized users can adjust their topics preferences. From 54ce30b2535f830fca71873292e401eb26a79cf6 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Wed, 22 Oct 2025 18:56:34 +0300 Subject: [PATCH 4/6] [2025.10] docs: update callout from "HINT" to "TIP" Revised the callout label to improve clarity and align with common terminology conventions in the documentation. --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index f9d2dbb..d7acff2 100644 --- a/index.md +++ b/index.md @@ -209,7 +209,7 @@ project's database. ## Challenge: Templates -> [!HINT] +> [!TIP] > Helpful link: > [Bootstrap template](https://github.com/devsforge/css-bootstrap-blog) From 624e1ace7781a0d7626c19b26f0ef5d6db02dfb8 Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Wed, 22 Oct 2025 19:02:58 +0300 Subject: [PATCH 5/6] [2025.10] docs: refine project specification for consistency Improved phrasing, grammar, and clarity across the project spec document. Aligned formatting and terminology with documentation standards. --- index.md | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/index.md b/index.md index d7acff2..8028ae3 100644 --- a/index.md +++ b/index.md @@ -1,11 +1,10 @@ # Blog Site The project aims to develop a robust and user-friendly web application using -the Django framework. The primary objective is to create a blogging platform -that allows users to publish and manage articles on various topics. -The application will provide an intuitive interface for authors to compose and -format their articles, while also offering a seamless reading experience for -visitors. +the Django framework. The primary goal is to create a blogging platform that +allows users to publish and manage articles on various topics. The application +will provide an intuitive interface for authors to compose and format their +articles, while also offering a seamless reading experience for visitors. ## Key Features @@ -38,14 +37,14 @@ management, and topic subscriptions, the application will empower users to create, share, and explore engaging content within a well-structured and organized platform. -Here is a starter repository template, that may help: +Here is a starter repository template that may help: [Starter template](https://github.com/devsforge/django-tpl.git). ## Challenge: Functional views -It's ok not to return **actual** content for now. Just ensure all the -routes are available and provide correct data. Use anything you like to -return within an HTTP response. +It's ok not to return **actual** content for now. Ensure all the routes are +available and provide correct data. Use anything you like to return within an +HTTP response. - `/about/`: Provides a regular text for a user, describing the functionalities of the django site. @@ -103,7 +102,7 @@ return within an HTTP response. **Article topic** -- This is a simple model, that contains information about topic: +- This is a simple model that contains information about a topic: - topic title (unique value, 64 characters or fewer) - topic short description (255 characters or fewer) @@ -113,7 +112,7 @@ return within an HTTP response. - Article requires content (at least 255 characters). - Creation date should be autogenerated at article creation and would never be updated. -- Updated date will be updated at each article save. +- Updated date will be updated at each article saved. **Article comment** @@ -145,7 +144,7 @@ return within an HTTP response. *article-user* relationship. - `topic` and `user` use *many-to-many* relationship. A single user can prefer none or as many topics as needed and vice versa. This relationship represents - topics preferred by a certain blog user. Also this provides an additional + topics preferred by a certain blog user. Also, this provides an additional option to mark some of the preferred topics with a **notify** flag to receive newsletters about specified topics updates. The difference between *prefer* and *notify* is that *preferred* topics affect the article list for a user, @@ -233,7 +232,7 @@ project's database. > Optional task(s) > > - Each page should contain a list of links to archive views for the last year. -> - Each page should contain an inclusion-block(s) with following links: +> - Each page should contain an inclusion-block(s) with the following links: > - `/registration/`: new user registration form > - `/login/`: user login form > - `/create/`: article creation page @@ -242,11 +241,11 @@ project's database. - The main page contains a list of published articles. - Each article entity is rendered using a custom template tag. -- `article` template tag renders information about a article object: +- `article` template tag renders information about an article object: - article title - article content (trimmed to \~50 characters) - article creation date - - related topics (3 topics or fewer) + - related topics (three topics or fewer) - number of related comments **Article details** @@ -354,7 +353,7 @@ project's database. the admin page. - `/register/`: Users should provide all required information about them: desired username and email. Name data (both first and last) is - optional. After user creation they should be redirected to login page + optional. After user creation they should be redirected to the login page to perform an authentication process. Invalid form should provide information about error(s). - `/login/`: Users should provide their credentials to login. In case @@ -367,9 +366,9 @@ project's database. created, it should be authored by the currently authenticated user. - `/
/comment/`: Currently authenticated user should be referenced as a comment's author. -- Articles may be modified or deleted only by their authors from the - detail article page. However, admins can still perform articles - actions from the admin page. +- Articles may be modified or deleted only by their authors from the detail + article page. However, admins can still perform article actions from the + admin page. - User-related paths are restricted for non-authorized users. - `/set-password/` - `/set-userdata/` @@ -390,7 +389,7 @@ project's database. for existing in the database. After that create a request for admin to activate an account and send a confirmation email, when all is done. -## Challenge: Article related forms +## Challenge: Article-related forms - Implement an article creation form. This form will be used to create new articles and to update existing ones. From f89cdb882ef268e1b211203c6a13f68a7dd7920a Mon Sep 17 00:00:00 2001 From: Serhii Horodilov Date: Thu, 23 Oct 2025 00:48:24 +0300 Subject: [PATCH 6/6] [release/2025.10] docs: clarify article ordering rules in spec Refined explanation for articles ordering logic to include publication date prioritization over topics in user preferences. Fixes: GH-1 --- index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.md b/index.md index 8028ae3..c430c84 100644 --- a/index.md +++ b/index.md @@ -204,7 +204,8 @@ project's database. > - Create a service to fetch articles ordered by specified user preferences. This means, topics preferred by a user affect articles order. Queryset should be ordered in a way, to have articles with most corresponding topics - at the begging. + at the begging. However, the publication date should be preferred over + the topic. ## Challenge: Templates