diff --git a/web/api/v1/blog/serializers.py b/web/api/v1/blog/serializers.py index 98ebfbd..1cc495d 100644 --- a/web/api/v1/blog/serializers.py +++ b/web/api/v1/blog/serializers.py @@ -60,7 +60,7 @@ class Meta(ArticleSerializer.Meta): class CreateArticleSerializer(serializers.ModelSerializer): # TaggitSerializer, - # tags = TagListSerializerField() + tags = TagListSerializerField() class Meta: model = Article @@ -69,17 +69,8 @@ class Meta: 'category', 'image', 'content', - ) # 'tags' - - def validate_title(self, title: str): - if is_article_slug_exist(title): - raise serializers.ValidationError('This title already exists') - return title - - @transaction.atomic() - def create(self, validated_data: dict): - validated_data['author'] = self.context['request'].user - return super().create(validated_data) + 'tags', + ) class ParentCommentSerializer(serializers.ModelSerializer): diff --git a/web/api/v1/blog/services.py b/web/api/v1/blog/services.py index 4e6f97f..7e5be2f 100644 --- a/web/api/v1/blog/services.py +++ b/web/api/v1/blog/services.py @@ -1,6 +1,9 @@ from django.db.models import Count, Prefetch, Q, QuerySet +from rest_framework.exceptions import ValidationError +from slugify import slugify from api.v1.actions.services import LikeQueryService +from api.v1.blog.types import CreateArticleT from blog.choices import ArticleStatus from blog.models import Article, ArticleTag, Category, Comment @@ -92,6 +95,19 @@ def get_article(self, article_id: int) -> Article: def get_comment(comment_id: int): return Comment.objects.get(id=comment_id) + +class CreateArticleService: + + @staticmethod + def _get_slug(value: str) -> str: + return slugify(value) + @staticmethod - def is_article_slug_exist(title: str) -> bool: - return Article.objects.filter(slug=Article.get_slug(title)).exists() + def is_article_slug_exist(slug: str) -> bool: + return Article.objects.filter(slug=slug).exists() + + def create_article(self, author: 'UserType', article_data: CreateArticleT) -> Article: + slug = self._get_slug(article_data['title']) + if self.is_article_slug_exist(slug): + raise ValidationError('Article with this title already exists') + return Article.objects.create(author=author, slug=slug, **article_data) diff --git a/web/api/v1/blog/types.py b/web/api/v1/blog/types.py new file mode 100644 index 0000000..c2ee090 --- /dev/null +++ b/web/api/v1/blog/types.py @@ -0,0 +1,14 @@ +from typing import TYPE_CHECKING, TypedDict + +if TYPE_CHECKING: + from django.core.files.uploadedfile import InMemoryUploadedFile + + from blog.models import Category + + +class CreateArticleT(TypedDict): + category: "Category" + title: str + content: str + image: "InMemoryUploadedFile" + tags: list[str] diff --git a/web/api/v1/blog/views.py b/web/api/v1/blog/views.py index 89827cc..2bfc79e 100644 --- a/web/api/v1/blog/views.py +++ b/web/api/v1/blog/views.py @@ -4,7 +4,7 @@ from . import serializers from .filters import ArticleFilter -from .services import BlogQueryService, CommentQueryService, TagQueryService, CategoryQueryService +from .services import BlogQueryService, CategoryQueryService, CommentQueryService, CreateArticleService, TagQueryService class ArticleListView(ListAPIView): @@ -34,8 +34,9 @@ class CreateArticleView(GenericAPIView): def post(self, request): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) - serializer.save() - return Response(serializer.data, status=status.HTTP_201_CREATED) + service = CreateArticleService() + article = service.create_article(request.user, serializer.validated_data) + return Response({'id': article.id}, status=status.HTTP_201_CREATED) class CommentListView(ListAPIView): diff --git a/web/blog/models.py b/web/blog/models.py index a0aba3c..fc84c71 100644 --- a/web/blog/models.py +++ b/web/blog/models.py @@ -67,14 +67,6 @@ def short_title(self) -> str: def __str__(self) -> str: return '{title} - {author}'.format(title=self.short_title, author=self.author) - @staticmethod - def get_slug(title: str) -> str: - return slugify(title, allow_unicode=True) - - def save(self, **kwargs): - self.slug = self.get_slug(self.title) - return super().save(**kwargs) - def get_absolute_url(self) -> str: return reverse_lazy('blog:blog-detail', kwargs={'slug': self.slug}) diff --git a/web/blog/static/blog/js/post_create.js b/web/blog/static/blog/js/post_create.js index dabc248..d6ed3b6 100644 --- a/web/blog/static/blog/js/post_create.js +++ b/web/blog/static/blog/js/post_create.js @@ -1,4 +1,5 @@ $(function () { + $('.category-select').select2(); $('#createArticleForm').submit(postCreate); getCategories(); }); @@ -14,7 +15,8 @@ function getCategories() { } function getCategoriesHandler (data) { - console.log('data', data); + const selector = $('.category-select') + data.forEach((category) => selector.append(new Option(category.name, category.id))) } function postCreate(event) { diff --git a/web/blog/templates/blog/post_create.html b/web/blog/templates/blog/post_create.html index 8b60be0..6214cdf 100644 --- a/web/blog/templates/blog/post_create.html +++ b/web/blog/templates/blog/post_create.html @@ -1,26 +1,27 @@ {% extends "blog/base.html" %} -{% load static main %} +{% load static %} {% block title %}New Post{% endblock title %} {% block head %} - + + {% endblock head %} {% block container %}