mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-07-14 17:45:46 +00:00
339 lines
12 KiB
Python
339 lines
12 KiB
Python
"""
|
|
web_admin serializers file
|
|
"""
|
|
# django imports
|
|
from rest_framework import serializers
|
|
from django.contrib.auth import get_user_model
|
|
|
|
from base.constants import (ARTICLE_SURVEY_POINTS, MAX_ARTICLE_CARD, MIN_ARTICLE_SURVEY, MAX_ARTICLE_SURVEY, NUMBER,
|
|
USER_TYPE, ARTICLE_CARD_IMAGE_FOLDER)
|
|
# local imports
|
|
from base.messages import ERROR_CODE
|
|
from guardian.utils import upload_image_to_alibaba
|
|
from web_admin.models import Article, ArticleCard, SurveyOption, ArticleSurvey, DefaultArticleCardImage
|
|
from web_admin.utils import pop_id, get_image_url
|
|
from junior.models import JuniorArticlePoints, JuniorArticle
|
|
USER = get_user_model()
|
|
|
|
|
|
class ArticleCardSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Article Card serializer
|
|
"""
|
|
id = serializers.IntegerField(required=False)
|
|
image_name = serializers.CharField(required=False)
|
|
image_url = serializers.CharField(required=False)
|
|
|
|
class Meta:
|
|
"""
|
|
meta class
|
|
"""
|
|
model = ArticleCard
|
|
fields = ('id', 'title', 'description', 'image_name', 'image_url')
|
|
|
|
def create(self, validated_data):
|
|
validated_data['image_url'] = get_image_url(validated_data)
|
|
article = Article.objects.all().first()
|
|
article_card = ArticleCard.objects.create(article=article, **validated_data)
|
|
return article_card
|
|
|
|
|
|
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)
|
|
options = SurveyOptionSerializer(many=True)
|
|
|
|
class Meta:
|
|
"""
|
|
meta class
|
|
"""
|
|
model = ArticleSurvey
|
|
fields = ('id', 'question', 'options')
|
|
|
|
|
|
class ArticleSerializer(serializers.ModelSerializer):
|
|
"""
|
|
serializer for article API
|
|
"""
|
|
article_cards = ArticleCardSerializer(many=True)
|
|
article_survey = ArticleSurveySerializer(many=True)
|
|
|
|
class Meta:
|
|
"""
|
|
meta class
|
|
"""
|
|
model = Article
|
|
fields = ('id', 'title', 'description', 'article_cards', 'article_survey')
|
|
|
|
def validate(self, attrs):
|
|
"""
|
|
to validate request data
|
|
: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(MAX_ARTICLE_CARD):
|
|
raise serializers.ValidationError({'details': ERROR_CODE['2039']})
|
|
if article_survey is None or len(article_survey) < int(MIN_ARTICLE_SURVEY) or int(
|
|
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.
|
|
:return: article object
|
|
"""
|
|
article_cards = validated_data.pop('article_cards')
|
|
article_survey = validated_data.pop('article_survey')
|
|
|
|
article = Article.objects.create(**validated_data)
|
|
|
|
for card in article_cards:
|
|
card = pop_id(card)
|
|
card['image_url'] = get_image_url(card)
|
|
ArticleCard.objects.create(article=article, **card)
|
|
|
|
for survey in article_survey:
|
|
survey = pop_id(survey)
|
|
options = survey.pop('options')
|
|
survey_obj = ArticleSurvey.objects.create(article=article, points=ARTICLE_SURVEY_POINTS, **survey)
|
|
for option in options:
|
|
option = pop_id(option)
|
|
SurveyOption.objects.create(survey=survey_obj, **option)
|
|
|
|
return article
|
|
|
|
def update(self, instance, validated_data):
|
|
"""
|
|
to update article and related table
|
|
:param instance: article object,
|
|
: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)
|
|
instance.description = validated_data.get('description', instance.description)
|
|
instance.save()
|
|
prev_card = list(ArticleCard.objects.filter(article=instance).values_list('id', flat=True))
|
|
# Update or create cards
|
|
for card_data in article_cards:
|
|
card_id = card_data.get('id', None)
|
|
if card_id:
|
|
prev_card.remove(card_id)
|
|
card = ArticleCard.objects.get(id=card_id, article=instance)
|
|
card.title = card_data.get('title', card.title)
|
|
card.description = card_data.get('description', card.description)
|
|
card.image_url = get_image_url(card_data)
|
|
card.save()
|
|
else:
|
|
card_data = pop_id(card_data)
|
|
card_data['image_url'] = get_image_url(card_data)
|
|
ArticleCard.objects.create(article=instance, **card_data)
|
|
ArticleCard.objects.filter(id__in=prev_card, article=instance).delete()
|
|
|
|
prev_survey = list(ArticleSurvey.objects.filter(article=instance).values_list('id', flat=True))
|
|
# Update or create survey sections
|
|
for survey_data in article_survey:
|
|
survey_id = survey_data.get('id', None)
|
|
options_data = survey_data.pop('options')
|
|
if survey_id:
|
|
prev_survey.remove(survey_id)
|
|
survey = ArticleSurvey.objects.get(id=survey_id, article=instance)
|
|
survey.question = survey_data.get('question', survey.question)
|
|
survey.save()
|
|
else:
|
|
survey_data = pop_id(survey_data)
|
|
survey = ArticleSurvey.objects.create(article=instance, points=ARTICLE_SURVEY_POINTS, **survey_data)
|
|
|
|
# Update or create survey options
|
|
for option_data in options_data:
|
|
option_id = option_data.get('id', None)
|
|
if option_id:
|
|
option = SurveyOption.objects.get(id=option_id, survey=survey)
|
|
option.option = option_data.get('option', option.option)
|
|
option.is_answer = option_data.get('is_answer', option.is_answer)
|
|
option.save()
|
|
else:
|
|
option_data = pop_id(option_data)
|
|
SurveyOption.objects.create(survey=survey, **option_data)
|
|
ArticleSurvey.objects.filter(id__in=prev_survey, article=instance).delete()
|
|
|
|
return instance
|
|
|
|
|
|
class DefaultArticleCardImageSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Article Card serializer
|
|
"""
|
|
image = serializers.FileField(required=False)
|
|
image_url = serializers.URLField(required=False)
|
|
|
|
class Meta:
|
|
"""
|
|
meta class
|
|
"""
|
|
model = DefaultArticleCardImage
|
|
fields = ('image_name', 'image', 'image_url')
|
|
|
|
def validate(self, attrs):
|
|
"""
|
|
to validate data
|
|
:return: validated data
|
|
"""
|
|
if 'image' not in attrs and attrs.get('image') is None:
|
|
raise serializers.ValidationError({'details': ERROR_CODE['2061']})
|
|
image = attrs.get('image')
|
|
if image and image.size == NUMBER['zero']:
|
|
raise serializers.ValidationError(ERROR_CODE['2035'])
|
|
return attrs
|
|
|
|
def create(self, validated_data):
|
|
"""
|
|
to create and upload image
|
|
:return: card_image object
|
|
"""
|
|
validated_data['image_url'] = get_image_url(validated_data)
|
|
|
|
card_image = DefaultArticleCardImage.objects.create(**validated_data)
|
|
return card_image
|
|
|
|
class ArticleListSerializer(serializers.ModelSerializer):
|
|
"""
|
|
serializer for article API
|
|
"""
|
|
image = serializers.SerializerMethodField('get_image')
|
|
total_points = serializers.SerializerMethodField('get_total_points')
|
|
is_completed = serializers.SerializerMethodField('get_is_completed')
|
|
|
|
class Meta(object):
|
|
"""
|
|
meta class
|
|
"""
|
|
model = Article
|
|
fields = ('id', 'title', 'description','image', 'total_points', 'is_completed')
|
|
|
|
def get_image(self, obj):
|
|
"""article image"""
|
|
if obj.article_cards.first():
|
|
return obj.article_cards.first().image_url
|
|
return None
|
|
def get_total_points(self, obj):
|
|
"""total points of article"""
|
|
total_question = ArticleSurvey.objects.filter(article=obj).count()
|
|
return total_question * NUMBER['five']
|
|
|
|
def get_is_completed(self, obj):
|
|
"""complete all question"""
|
|
context_data = self.context.get('user')
|
|
junior_article = JuniorArticle.objects.filter(junior__auth=context_data, article=obj).last()
|
|
if junior_article:
|
|
return junior_article.is_completed
|
|
return False
|
|
|
|
class ArticleQuestionSerializer(serializers.ModelSerializer):
|
|
"""
|
|
article survey serializer
|
|
"""
|
|
id = serializers.IntegerField(required=False)
|
|
options = SurveyOptionSerializer(many=True)
|
|
is_attempt = serializers.SerializerMethodField('get_is_attempt')
|
|
correct_answer = serializers.SerializerMethodField('get_correct_answer')
|
|
attempted_answer = serializers.SerializerMethodField('get_attempted_answer')
|
|
|
|
|
|
def get_is_attempt(self, obj):
|
|
"""attempt question or not"""
|
|
context_data = self.context.get('user')
|
|
junior_article_obj = JuniorArticlePoints.objects.filter(junior__auth=context_data, question=obj).last()
|
|
if junior_article_obj:
|
|
return junior_article_obj.is_attempt
|
|
return False
|
|
|
|
def get_correct_answer(self, obj):
|
|
"""attempt question or not"""
|
|
ans_obj = SurveyOption.objects.filter(survey=obj, is_answer=True).last()
|
|
if ans_obj:
|
|
return ans_obj.id
|
|
return str("None")
|
|
|
|
def get_attempted_answer(self, obj):
|
|
"""attempt question or not"""
|
|
context_data = self.context.get('user')
|
|
junior_article_obj = JuniorArticlePoints.objects.filter(junior__auth=context_data,
|
|
question=obj, is_answer_correct=True).last()
|
|
if junior_article_obj:
|
|
return junior_article_obj.submitted_answer.id
|
|
return None
|
|
|
|
class Meta(object):
|
|
"""
|
|
meta class
|
|
"""
|
|
model = ArticleSurvey
|
|
fields = ('id', 'question', 'options', 'points', 'is_attempt', 'correct_answer', 'attempted_answer')
|
|
|
|
class StartAssessmentSerializer(serializers.ModelSerializer):
|
|
"""
|
|
serializer for article API
|
|
"""
|
|
article_survey = ArticleQuestionSerializer(many=True)
|
|
current_page = serializers.SerializerMethodField('get_current_page')
|
|
|
|
def get_current_page(self, obj):
|
|
"""current page"""
|
|
context_data = self.context.get('user')
|
|
data = JuniorArticle.objects.filter(junior__auth=context_data, article=obj).last()
|
|
if data:
|
|
return data.current_que_page
|
|
return NUMBER['zero']
|
|
class Meta(object):
|
|
"""
|
|
meta class
|
|
"""
|
|
model = Article
|
|
fields = ('article_survey', 'current_page')
|
|
|
|
|
|
|
|
class ArticleCardlistSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Article Card serializer
|
|
"""
|
|
id = serializers.IntegerField(required=False)
|
|
image_name = serializers.CharField(required=False)
|
|
image_url = serializers.CharField(required=False)
|
|
current_page = serializers.SerializerMethodField('get_current_page')
|
|
|
|
def get_current_page(self, obj):
|
|
"""current page"""
|
|
context_data = self.context.get('user')
|
|
data = JuniorArticle.objects.filter(junior__auth=context_data, article=obj.article).last()
|
|
if data:
|
|
return data.current_card_page
|
|
return NUMBER['zero']
|
|
|
|
class Meta(object):
|
|
"""
|
|
meta class
|
|
"""
|
|
model = ArticleCard
|
|
fields = ('id', 'title', 'description', 'image_name', 'image_url', 'current_page')
|