Skip to content

Commit

Permalink
post create
Browse files Browse the repository at this point in the history
  • Loading branch information
Nazarii committed Mar 21, 2024
1 parent c97e7ce commit 100be3f
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 37 deletions.
15 changes: 3 additions & 12 deletions web/api/v1/blog/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Meta(ArticleSerializer.Meta):


class CreateArticleSerializer(serializers.ModelSerializer): # TaggitSerializer,
# tags = TagListSerializerField()
tags = TagListSerializerField()

class Meta:
model = Article
Expand All @@ -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):
Expand Down
20 changes: 18 additions & 2 deletions web/api/v1/blog/services.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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)
14 changes: 14 additions & 0 deletions web/api/v1/blog/types.py
Original file line number Diff line number Diff line change
@@ -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]
7 changes: 4 additions & 3 deletions web/api/v1/blog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down
8 changes: 0 additions & 8 deletions web/blog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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})

Expand Down
4 changes: 3 additions & 1 deletion web/blog/static/blog/js/post_create.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
$(function () {
$('.category-select').select2();
$('#createArticleForm').submit(postCreate);
getCategories();
});
Expand All @@ -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) {
Expand Down
20 changes: 11 additions & 9 deletions web/blog/templates/blog/post_create.html
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
{% extends "blog/base.html" %}
{% load static main %}
{% load static %}

{% block title %}New Post{% endblock title %}

{% block head %}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-lite.min.css" rel="stylesheet">

<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.1.0-beta.1/css/select2.min.css" rel="stylesheet" />
<style>
.category-select {
width: 200px;
}
</style>
{% endblock head %}

{% block container %}

<h1>Create a new post</h1>
<form id="createArticleForm" method="post" enctype="multipart/form-data"
name="fileinfo">
<form id="createArticleForm" method="post" enctype="multipart/form-data" name="fileinfo">
<div id="categoryGroup">
<label>Category: </label>
<select class="form-control" name="category" style="width: 40%">
{% for category in categories %}
<option value="{{ category.id }}">{{ category.name }}</option>
{% endfor %}
</select>
<select class="category-select form-select category-select" name="category"></select>
</div>

<hr>
<div id="titleGroup">
<label>Article Title: </label>
Expand Down Expand Up @@ -50,6 +51,7 @@ <h1>Create a new post</h1>

{% block script %}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-lite.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.1.0-beta.1/js/select2.min.js"></script>
<script>
$('#summernote').summernote({
placeholder: 'Content',
Expand Down
1 change: 1 addition & 0 deletions web/src/requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ djangorestframework~=3.14
drf-spectacular~=0.27
celery~=5.3
graphene-django==3.0
python-slugify~=8.0

### Optional dependencies ###

Expand Down
2 changes: 0 additions & 2 deletions web/templates/includes/footer.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{% load static main blog %}
{% categories as categories %}


<footer>
<div class="row">
Expand Down

0 comments on commit 100be3f

Please sign in to comment.