mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-15 18:07:02 +00:00
added admin permission
This commit is contained in:
@ -65,7 +65,12 @@ ERROR_CODE = {
|
||||
"2036": "Choose valid user",
|
||||
# log in multiple device msg
|
||||
"2037": "You are already log in another device",
|
||||
"2038": "Choose valid action for task"
|
||||
"2038": "Choose valid action for task",
|
||||
"2039": "Add at least one article card or maximum 6",
|
||||
"2040": "Add at least 5 article survey or maximum 10",
|
||||
"2041": "Article with given id doesn't exist.",
|
||||
"2042": "Article Card with given id doesn't exist.",
|
||||
"2043": "Article Survey with given id doesn't exist."
|
||||
}
|
||||
"""Success message code"""
|
||||
SUCCESS_CODE = {
|
||||
@ -105,6 +110,11 @@ SUCCESS_CODE = {
|
||||
"3024": "Junior request is rejected successfully",
|
||||
"3025": "Task is approved successfully",
|
||||
"3026": "Task is rejected successfully",
|
||||
"3027": "Article has been created successfully.",
|
||||
"3028": "Article has been updated successfully.",
|
||||
"3029": "Article has been deleted successfully.",
|
||||
"3030": "Article Card has been removed successfully.",
|
||||
"3031": "Article Survey has been removed successfully.",
|
||||
}
|
||||
"""status code error"""
|
||||
STATUS_CODE_ERROR = {
|
||||
|
@ -1,5 +1,10 @@
|
||||
"""
|
||||
web_admin admin file
|
||||
"""
|
||||
# django imports
|
||||
from django.contrib import admin
|
||||
|
||||
# local imports
|
||||
from web_admin.models import Article, ArticleCard, ArticleSurvey, SurveyOption
|
||||
|
||||
|
||||
|
@ -1,6 +1,13 @@
|
||||
"""
|
||||
web_admin app file
|
||||
"""
|
||||
# django imports
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WebAdminConfig(AppConfig):
|
||||
"""
|
||||
web admin app config
|
||||
"""
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'web_admin'
|
||||
|
@ -6,6 +6,9 @@ from django.db import models
|
||||
|
||||
|
||||
class Article(models.Model):
|
||||
"""
|
||||
Article model
|
||||
"""
|
||||
title = models.CharField(max_length=255)
|
||||
description = models.TextField()
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
@ -19,6 +22,9 @@ class Article(models.Model):
|
||||
|
||||
|
||||
class ArticleCard(models.Model):
|
||||
"""
|
||||
Article Card model
|
||||
"""
|
||||
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='article_cards')
|
||||
title = models.CharField(max_length=255)
|
||||
description = models.TextField()
|
||||
@ -32,6 +38,9 @@ class ArticleCard(models.Model):
|
||||
|
||||
|
||||
class ArticleSurvey(models.Model):
|
||||
"""
|
||||
Article Survey model
|
||||
"""
|
||||
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='article_survey')
|
||||
question = models.CharField(max_length=255)
|
||||
points = models.IntegerField()
|
||||
@ -44,6 +53,9 @@ class ArticleSurvey(models.Model):
|
||||
|
||||
|
||||
class SurveyOption(models.Model):
|
||||
"""
|
||||
Survey Options model
|
||||
"""
|
||||
survey = models.ForeignKey(ArticleSurvey, on_delete=models.CASCADE, related_name='survey_options')
|
||||
option = models.CharField(max_length=255)
|
||||
is_answer = models.BooleanField(default=False)
|
||||
|
26
web_admin/permission.py
Normal file
26
web_admin/permission.py
Normal file
@ -0,0 +1,26 @@
|
||||
"""
|
||||
web_admin permission classes
|
||||
"""
|
||||
# django imports
|
||||
from rest_framework import permissions
|
||||
|
||||
|
||||
class AdminPermission(permissions.BasePermission):
|
||||
"""
|
||||
to check for usertype admin only
|
||||
"""
|
||||
def has_permission(self, request, view):
|
||||
"""
|
||||
Return True if user_type is admin
|
||||
"""
|
||||
if request.user.is_superuser:
|
||||
return True
|
||||
return False
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
"""
|
||||
check for object level permission
|
||||
"""
|
||||
if request.user.is_superuser:
|
||||
return True
|
||||
return False
|
@ -1,33 +1,55 @@
|
||||
"""
|
||||
web_admin serializers file
|
||||
"""
|
||||
# django imports
|
||||
from rest_framework import serializers
|
||||
from django.conf import settings
|
||||
|
||||
# local imports
|
||||
from base.messages import ERROR_CODE
|
||||
from web_admin.models import Article, ArticleCard, SurveyOption, ArticleSurvey
|
||||
from web_admin.utils import pop_id
|
||||
|
||||
|
||||
class ArticleCardSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
Article Card serializer
|
||||
"""
|
||||
id = serializers.IntegerField(required=False)
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
meta class
|
||||
"""
|
||||
model = ArticleCard
|
||||
fields = ('id', 'title', 'description')
|
||||
|
||||
|
||||
class SurveyOptionSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
survey option serializer
|
||||
"""
|
||||
id = serializers.IntegerField(required=False)
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
meta class
|
||||
"""
|
||||
model = SurveyOption
|
||||
fields = ('id', 'option', 'is_answer')
|
||||
|
||||
|
||||
class ArticleSurveySerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
article survey serializer
|
||||
"""
|
||||
id = serializers.IntegerField(required=False)
|
||||
survey_options = SurveyOptionSerializer(many=True)
|
||||
|
||||
class Meta:
|
||||
"""
|
||||
meta class
|
||||
"""
|
||||
model = ArticleSurvey
|
||||
fields = ('id', 'question', 'points', 'survey_options')
|
||||
|
||||
@ -46,12 +68,27 @@ class ArticleSerializer(serializers.ModelSerializer):
|
||||
model = Article
|
||||
fields = ('id', 'title', 'description', 'article_cards', 'article_survey')
|
||||
|
||||
def validate(self, attrs):
|
||||
"""
|
||||
to validate request data
|
||||
:param attrs:
|
||||
:return: validated attrs
|
||||
"""
|
||||
article_cards = attrs.get('article_cards', None)
|
||||
article_survey = attrs.get('article_survey', None)
|
||||
if article_cards is None or len(article_cards) > int(settings.MAX_ARTICLE_CARD):
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2039']})
|
||||
if article_survey is None or len(article_survey) < int(settings.MIN_ARTICLE_SURVEY) or int(
|
||||
settings.MAX_ARTICLE_SURVEY) < len(article_survey):
|
||||
raise serializers.ValidationError({'details': ERROR_CODE['2040']})
|
||||
return attrs
|
||||
|
||||
def create(self, validated_data):
|
||||
"""
|
||||
to create article.
|
||||
ID in post data dict is for update api.
|
||||
:param validated_data:
|
||||
:return: success message
|
||||
:return: article object
|
||||
"""
|
||||
article_cards = validated_data.pop('article_cards')
|
||||
article_survey = validated_data.pop('article_survey')
|
||||
@ -73,6 +110,12 @@ class ArticleSerializer(serializers.ModelSerializer):
|
||||
return article
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
"""
|
||||
to update article and related table
|
||||
:param instance:
|
||||
:param validated_data:
|
||||
:return: article object
|
||||
"""
|
||||
article_cards = validated_data.pop('article_cards')
|
||||
article_survey = validated_data.pop('article_survey')
|
||||
instance.title = validated_data.get('title', instance.title)
|
||||
|
@ -1,3 +1,6 @@
|
||||
"""
|
||||
web_admin test file
|
||||
"""
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
@ -5,8 +5,10 @@ web_admin urls file
|
||||
from django.urls import path, include
|
||||
from rest_framework import routers
|
||||
|
||||
# local imports
|
||||
from web_admin.views import ArticleViewSet
|
||||
|
||||
# initiate router
|
||||
router = routers.SimpleRouter()
|
||||
|
||||
router.register('article', ArticleViewSet, basename='article')
|
||||
|
@ -5,50 +5,138 @@ web_admin views file
|
||||
from rest_framework.viewsets import GenericViewSet, mixins
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
# local imports
|
||||
from account.utils import custom_response, custom_error_response
|
||||
from web_admin.models import Article
|
||||
from base.messages import SUCCESS_CODE, ERROR_CODE
|
||||
from web_admin.models import Article, ArticleCard, ArticleSurvey
|
||||
from web_admin.permission import AdminPermission
|
||||
from web_admin.serializers import ArticleSerializer
|
||||
|
||||
|
||||
class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModelMixin,
|
||||
mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.DestroyModelMixin):
|
||||
"""
|
||||
article api
|
||||
"""
|
||||
serializer_class = ArticleSerializer
|
||||
permission_classes = []
|
||||
permission_classes = [IsAuthenticated, AdminPermission]
|
||||
queryset = Article.objects.prefetch_related('article_cards',
|
||||
'article_survey',
|
||||
'article_survey__survey_options')
|
||||
'article_survey__survey_options').order_by('-created_at')
|
||||
|
||||
http_method_names = ['get', 'post', 'put', 'delete']
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
"""
|
||||
article create api method
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return: success message
|
||||
"""
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return custom_response("created")
|
||||
return custom_response(SUCCESS_CODE["3027"])
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
"""
|
||||
article update api method
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return: success message
|
||||
"""
|
||||
article = self.queryset.filter(id=kwargs['pk']).first()
|
||||
serializer = self.serializer_class(article, data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return custom_response("updated")
|
||||
return custom_response(SUCCESS_CODE["3028"])
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
# queryset = Article.objects.prefetch_related('article_cards',
|
||||
# 'article_survey',
|
||||
# 'article_survey__survey_options')
|
||||
"""
|
||||
article list api method
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return: list of article
|
||||
"""
|
||||
queryset = self.queryset.filter(is_deleted=False)
|
||||
paginator = self.pagination_class()
|
||||
paginated_queryset = paginator.paginate_queryset(self.queryset, request)
|
||||
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||
serializer = self.serializer_class(paginated_queryset, many=True)
|
||||
return custom_response(None, data=serializer.data)
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
queryset = self.queryset.filter(id=kwargs['pk'])
|
||||
"""
|
||||
article detail api method
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return: article detail data
|
||||
"""
|
||||
queryset = self.queryset.filter(id=kwargs['pk'], is_deleted=False)
|
||||
serializer = self.serializer_class(queryset, many=True)
|
||||
return custom_response(None, data=serializer.data)
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
"""
|
||||
article delete (soft delete) api method
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return: success message
|
||||
"""
|
||||
article = self.queryset.filter(id=kwargs['pk']).update(is_deleted=True)
|
||||
if article:
|
||||
return custom_response("deleted")
|
||||
return custom_error_response("article doesn't exist", status.HTTP_400_BAD_REQUEST)
|
||||
return custom_response(SUCCESS_CODE["3029"])
|
||||
return custom_error_response(ERROR_CODE["2041"], status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@action(methods=['get'], url_name='', url_path='', detail=False)
|
||||
def search_article(self, request):
|
||||
"""
|
||||
article search api method
|
||||
:param request:
|
||||
:return: searched article
|
||||
"""
|
||||
search = request.GET.get('search')
|
||||
queryset = self.queryset.filter(title__icontains=search)
|
||||
paginator = self.pagination_class()
|
||||
paginated_queryset = paginator.paginate_queryset(queryset, request)
|
||||
serializer = self.serializer_class(paginated_queryset, many=True)
|
||||
return custom_response(None, data=serializer.data)
|
||||
|
||||
@action(methods=['get'], url_name='remove_card', url_path='remove_card',
|
||||
detail=True, serializer_class=None)
|
||||
def remove_article_card(self, request, *args, **kwargs):
|
||||
"""
|
||||
article card remove (delete) api method
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return: success message
|
||||
"""
|
||||
try:
|
||||
ArticleCard.objects.filter(id=kwargs['pk']).first().delete()
|
||||
return custom_response(SUCCESS_CODE["3030"])
|
||||
except AttributeError:
|
||||
return custom_error_response(ERROR_CODE["2042"], response_status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@action(methods=['get'], url_name='remove_survey', url_path='remove_survey',
|
||||
detail=True, serializer_class=None)
|
||||
def remove_article_survey(self, request, *args, **kwargs):
|
||||
"""
|
||||
article survey remove (delete) api method
|
||||
:param request:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return: success message
|
||||
"""
|
||||
try:
|
||||
ArticleSurvey.objects.filter(id=kwargs['pk']).first().delete()
|
||||
return custom_response(SUCCESS_CODE["3031"])
|
||||
except AttributeError:
|
||||
return custom_error_response(ERROR_CODE["2043"], response_status=status.HTTP_400_BAD_REQUEST)
|
||||
|
@ -233,6 +233,10 @@ ALIYUN_OSS_BUCKET_NAME = os.getenv('ALIYUN_OSS_BUCKET_NAME')
|
||||
ALIYUN_OSS_ENDPOINT = os.getenv('ALIYUN_OSS_ENDPOINT')
|
||||
ALIYUN_OSS_REGION = os.getenv('ALIYUN_OSS_REGION')
|
||||
|
||||
MAX_ARTICLE_CARD = os.getenv('MAX_ARTICLE_CARD', 6)
|
||||
MIN_ARTICLE_SURVEY = os.getenv('MIN_ARTICLE_SURVEY', 5)
|
||||
MAX_ARTICLE_SURVEY = os.getenv('MAX_ARTICLE_SURVEY', 10)
|
||||
|
||||
# define static url
|
||||
STATIC_URL = 'static/'
|
||||
# define static root
|
||||
|
Reference in New Issue
Block a user