Skip to content

Commit

Permalink
following refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Nazarii committed Dec 17, 2023
1 parent 78d77ff commit 27aceb8
Show file tree
Hide file tree
Showing 19 changed files with 92 additions and 157 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules
web/dist
web/build
web/static/
Pip*
Pipfile*
Expand Down Expand Up @@ -31,3 +33,4 @@ modules.txt
postgresql-*.tgz

db.sqlite3
*.spec
8 changes: 5 additions & 3 deletions web/actions/choices.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from enum import Enum

from django.db.models import IntegerChoices, TextChoices
from django.utils.translation import gettext_lazy as _

Expand All @@ -18,9 +20,9 @@ class LikeIconStatus(IntegerChoices):
EMPTY = 0


class FollowIconStatus(TextChoices):
FOLLOW = ('Follow', _('Follow'))
UNFOLLOW = ('Unfollow', _('Unfollow'))
class FollowStatus(Enum):
FOLLOW = True
UNFOLLOW = False


class UserActionsChoice(IntegerChoices):
Expand Down
20 changes: 0 additions & 20 deletions web/actions/serializers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers

from .choices import FollowIconStatus
from .models import Action, LikeDislike
from .services import ActionsService

User = get_user_model()

Expand All @@ -14,24 +12,6 @@ class Meta:
fields = ('vote', 'user', 'date')


class UserFollowSerializer(serializers.ModelSerializer):
"""For list of user following and followers"""

profile_url = serializers.URLField(source='get_absolute_url')
follow = serializers.SerializerMethodField('get_follow_status')

def get_follow_status(self, obj) -> str:
user = self.context['request'].user
if user == obj:
return None
is_follow = ActionsService.is_user_followed(user, obj.id)
return FollowIconStatus.UNFOLLOW if is_follow else FollowIconStatus.FOLLOW

class Meta:
model = User
fields = ('id', 'full_name', 'avatar', 'profile_url', 'follow')


class ActionListSerializer(serializers.ModelSerializer):
class Meta:
model = Action
Expand Down
10 changes: 6 additions & 4 deletions web/actions/static/actions/js/follow.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ $(function () {
});

function followMe() {
console.log('click')
let button = $(this)
let data = {
'user_id': button.data('id')
}

$.ajax({
url: button.data('href'),
url: '/api/v1/actions/follow',
type: 'post',
data: data,
success: function (data) {
console.log(data, "success")
button.text(data.status)
button.text(getButtonText(data.status))
}
})
}

function getButtonText(followStatus) {
return followStatus === true ? 'Unfollow' : 'Follow'
}
6 changes: 3 additions & 3 deletions web/api/v1/actions/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers

from actions.choices import FollowIconStatus, LikeObjChoice, LikeStatus
from actions.choices import FollowStatus, LikeObjChoice, LikeStatus
from api.v1.actions.services import FollowService

if TYPE_CHECKING:
Expand All @@ -30,12 +30,12 @@ class UserFollowSerializer(serializers.ModelSerializer):

follow = serializers.SerializerMethodField('get_follow_status')

def get_follow_status(self, obj) -> Optional[FollowIconStatus]:
def get_follow_status(self, obj) -> Optional[FollowStatus]:
user = self.context['request'].user
if user == obj:
return None
is_follow = FollowService(user=user, user_id=obj.id).is_user_subscribed()
return FollowIconStatus.UNFOLLOW if is_follow else FollowIconStatus.FOLLOW
return FollowStatus.UNFOLLOW if is_follow else FollowStatus.FOLLOW

class Meta:
model = User
Expand Down
12 changes: 5 additions & 7 deletions web/api/v1/actions/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import NotFound

from actions.choices import FollowIconStatus, LikeIconStatus, LikeObjChoice, LikeStatus
from actions.choices import FollowStatus, LikeIconStatus, LikeObjChoice, LikeStatus
from actions.models import Follower, LikeDislike
from blog.models import Article, Comment

Expand Down Expand Up @@ -99,16 +99,14 @@ def subscribe_to_user(self) -> Follower:
def unfollow_user(self):
return Follower.objects.filter(subscriber=self.user, to_user_id=self.to_user_id).delete()

def subscribe(self) -> dict:
def subscribe(self) -> bool:
if not self.is_user_subscribed():
self.subscribe_to_user()
follow_status = FollowIconStatus.UNFOLLOW
follow_status = FollowStatus.FOLLOW
else:
self.unfollow_user()
follow_status = FollowIconStatus.FOLLOW
return {
'status': follow_status,
}
follow_status = FollowStatus.UNFOLLOW
return follow_status.value


class FollowersQueryService:
Expand Down
4 changes: 2 additions & 2 deletions web/api/v1/actions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def post(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
service = FollowService(user=request.user, user_id=serializer.data['user_id'])
response_data = service.subscribe()
return Response(response_data, status.HTTP_200_OK)
follow_status = service.subscribe()
return Response({'status': follow_status}, status.HTTP_200_OK)


class UserFollowersView(ListModelMixin, GenericViewSet):
Expand Down
4 changes: 2 additions & 2 deletions web/api/v1/auth_app/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ def user(self) -> User:
return self._user

def validate(self):
self._user = self._get_user_by_uid_or_exception(self._uid)
self._user = self._get_user_by_uid(self._uid)
self._validate_token()

@staticmethod
def _get_user_by_uid_or_exception(uid: str) -> User:
def _get_user_by_uid(uid: str) -> User:
try:
uid = force_str(urlsafe_base64_decode(uid))
return User.objects.get(id=uid)
Expand Down
23 changes: 14 additions & 9 deletions web/api/v1/blog/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,28 @@ class Meta(ArticleSerializer.Meta):
fields = ArticleSerializer.Meta.fields + ('votes',)


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

class Meta:
model = Article
fields = ('title', 'category', 'image', 'content', 'tags')

@transaction.atomic()
def create(self, validated_data):
validated_data['author'] = self.context.get('request').user
return super().create(validated_data)
fields = (
'title',
'category',
'image',
'content',
) # 'tags'

def validate_title(self, title: str):
if BlogService.is_article_slug_exist(title):
raise serializers.ValidationError("This title already exists")
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)


class ParentCommentSerializer(serializers.ModelSerializer):
user = ShortUserSerializer(read_only=True)
Expand Down
9 changes: 1 addition & 8 deletions web/api/v1/profile/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers

from actions.choices import FollowIconStatus
from api.v1.actions.services import FollowService

User = get_user_model()

Expand Down Expand Up @@ -88,12 +86,7 @@ def update(self, instance: User, validated_data: dict):


class UserListSerializer(serializers.ModelSerializer):
follow = serializers.SerializerMethodField('get_follow_status')

def get_follow_status(self, obj) -> str:
user = self.context['request'].user
is_follow = FollowService(user, obj.id).is_user_subscribed()
return FollowIconStatus.UNFOLLOW if is_follow else FollowIconStatus.FOLLOW
follow = serializers.BooleanField()

class Meta:
model = User
Expand Down
8 changes: 7 additions & 1 deletion web/api/v1/profile/services.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from typing import TYPE_CHECKING, Optional

from django.contrib.auth import get_user_model
from django.db.models import Count, Q
from django.db.models import Count, Exists, OuterRef, Q

from actions.models import Follower
from blog.choices import ArticleStatus

from main.decorators import except_shell
Expand Down Expand Up @@ -33,6 +34,11 @@ def user_profile_queryset(self) -> 'QuerySet[User]':
user_likes = Count('likes')
return self.get_queryset(is_active=True).annotate(user_posts=user_articles, user_likes=user_likes)

def user_list_queryset(self, current_user: User) -> 'QuerySet[User]':
return self.user_profile_queryset().annotate(
follow=Exists(Follower.objects.filter(subscriber=current_user, to_user_id=OuterRef('pk')))
)

@except_shell((User.DoesNotExist,), raise_404=True)
def get_user_profile(self, user_id: int) -> User:
return self.user_profile_queryset().get(id=user_id)
2 changes: 1 addition & 1 deletion web/api/v1/profile/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ class UserListView(ListAPIView):
serializer_class = serializers.UserListSerializer

def get_queryset(self):
return UserQueryService.get_queryset(is_active=True)
return UserQueryService().user_list_queryset(current_user=self.request.user)
7 changes: 0 additions & 7 deletions web/blog/urls.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
from django.urls import path
from rest_framework.routers import DefaultRouter

from . import views
from main.views import TemplateAPIView

app_name = 'blog'

router = DefaultRouter()
router.register('comment', views.CommentViewSet, basename='comment')

urlpatterns = [
path('blog/', TemplateAPIView.as_view(template_name='blog/post_list.html'), name='blog-list'),
path('blog/<str:slug>', TemplateAPIView.as_view(template_name='blog/post_detail.html'), name='blog-detail'),
path('comment/<article_id>/', views.CommentViewSet.as_view({'get': 'list'}), name='article_comments'),
path('posts/new/', views.CreateArticleTemplateView.as_view(), name='new_post'),
]

urlpatterns += router.urls
41 changes: 0 additions & 41 deletions web/blog/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,47 +22,6 @@ class ViewSet(ModelViewSet):
pagination_class = BasePageNumberPagination


class CommentViewSet(mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, GenericViewSet):
permission_classes = (AllowAny,)
http_method_names = ('get', 'post', 'put', 'delete')
pagination_class = BasePageNumberPagination

def get_serializer_class(self):
if self.action == 'update' or self.action == 'destroy':
return serializers.UpdateDestroyCommentSerializer
return serializers.CommentSerializer

def get_queryset(self):
return BlogService.get_comments_queryset()

def get_object(self):
return BlogService.get_article_comments(article_id=self.kwargs.get('article_id'))

def list(self, request, article_id):
queryset = self.filter_queryset(self.get_object())

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

def update(self, request, **kwargs):
serializer = self.get_serializer(self.get_object(), data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)

def destroy(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data)
serializer.is_valid(raise_exception=True)
instance.delete()
return Response(status=status.HTTP_204_NO_CONTENT)


class CreateArticleTemplateView(TemplateAPIView):
template_name = 'blog/post_create.html'

Expand Down
16 changes: 0 additions & 16 deletions web/user_profile/serializers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from django.contrib.auth import get_user_model
from rest_framework import serializers

from actions.choices import FollowIconStatus
from api.v1.actions.services import FollowService

from main.models import GenderChoice

User = get_user_model()
Expand Down Expand Up @@ -43,16 +40,3 @@ class UpdateUserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'first_name', 'last_name', 'birthday', 'gender')


class UserListSerializer(serializers.ModelSerializer):
follow = serializers.SerializerMethodField('get_follow_status')

def get_follow_status(self, obj) -> str:
user = self.context['request'].user
is_follow = FollowService(user, obj.id).is_user_subscribed()
return FollowIconStatus.UNFOLLOW if is_follow else FollowIconStatus.FOLLOW

class Meta:
model = User
fields = ('id', 'full_name', 'avatar', 'follow')
40 changes: 40 additions & 0 deletions web/user_profile/static/user_profile/js/user_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
$(function () {
userList()
});


function userList() {
$.ajax({
type: 'GET',
url: '/api/v1/user/',
success: userListHandler,
})
}

function userListTemplate(user) {
const followButtonText = getButtonText(user.follow)
return `
<li class="span5 clearfix">
<div class="thumbnail clearfix">
<img src="${user.avatar}" alt="Avatar" class="pull-left span2 clearfix avatar img-circle img-thumbnail" width="120px"
style='margin-right:10px'>
<div class="caption" class="pull-left">
<a href="#" data-id="${user.id}"
class="btn btn-primary icon pull-right followMe">${followButtonText}</a>
<h4>
<a href="/user/${user.id}">${ user.full_name}</a>
</h4>
<small><b>RG: </b>99384877</small>
</div>
</div>
</li>
`
}

function userListHandler(data) {
const userList = $('#userList');
const result = data.results.map((user) => userListTemplate(user)).join('');
userList.empty();
userList.append(result);
$(".followMe").click(followMe);
}
Loading

0 comments on commit 27aceb8

Please sign in to comment.