list, view, edit api for article

This commit is contained in:
abutalib-kiwi
2023-07-14 18:47:07 +05:30
parent a4d9997580
commit 45410fa0ca
6 changed files with 136 additions and 26 deletions

View File

@ -5,23 +5,23 @@ from web_admin.models import Article, ArticleCard, ArticleSurvey, SurveyOption
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
"""Junior Points Admin"""
list_display = ['id', 'title', 'description', 'is_published']
"""Article Admin"""
list_display = ['id', 'title', 'description', 'is_published', 'is_deleted']
@admin.register(ArticleCard)
class ArticleAdmin(admin.ModelAdmin):
"""Junior Points Admin"""
class ArticleCardAdmin(admin.ModelAdmin):
"""Article Card Admin"""
list_display = ['id', 'article', 'title', 'description', 'image']
@admin.register(ArticleSurvey)
class ArticleAdmin(admin.ModelAdmin):
"""Junior Points Admin"""
class ArticleSurveyAdmin(admin.ModelAdmin):
"""Article Survey Admin"""
list_display = ['id', 'article', 'question', 'points']
@admin.register(SurveyOption)
class ArticleAdmin(admin.ModelAdmin):
"""Junior Points Admin"""
class SurveyOptionAdmin(admin.ModelAdmin):
"""Survey Option Admin"""
list_display = ['id', 'survey', 'option', 'is_answer']

View File

@ -1,4 +1,4 @@
# Generated by Django 4.2.2 on 2023-07-13 13:01
# Generated by Django 4.2.2 on 2023-07-14 13:15
from django.db import migrations, models
import django.db.models.deletion
@ -20,7 +20,8 @@ class Migration(migrations.Migration):
('description', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('is_published', models.BooleanField(default=False)),
('is_published', models.BooleanField(default=True)),
('is_deleted', models.BooleanField(default=False)),
],
),
migrations.CreateModel(
@ -31,7 +32,7 @@ class Migration(migrations.Migration):
('points', models.IntegerField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web_admin.article')),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='article_survey', to='web_admin.article')),
],
),
migrations.CreateModel(
@ -42,7 +43,7 @@ class Migration(migrations.Migration):
('is_answer', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('survey', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web_admin.articlesurvey')),
('survey', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='survey_options', to='web_admin.articlesurvey')),
],
),
migrations.CreateModel(
@ -54,7 +55,7 @@ class Migration(migrations.Migration):
('image', models.ImageField(upload_to='card_images/')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web_admin.article')),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='article_cards', to='web_admin.article')),
],
),
]

View File

@ -10,7 +10,8 @@ class Article(models.Model):
description = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
is_published = models.BooleanField(default=False)
is_published = models.BooleanField(default=True)
is_deleted = models.BooleanField(default=False)
def __str__(self):
"""Return title"""
@ -18,7 +19,7 @@ class Article(models.Model):
class ArticleCard(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='article_cards')
title = models.CharField(max_length=255)
description = models.TextField()
image = models.ImageField(upload_to='card_images/')
@ -31,7 +32,7 @@ class ArticleCard(models.Model):
class ArticleSurvey(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='article_survey')
question = models.CharField(max_length=255)
points = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
@ -43,7 +44,7 @@ class ArticleSurvey(models.Model):
class SurveyOption(models.Model):
survey = models.ForeignKey(ArticleSurvey, on_delete=models.CASCADE)
survey = models.ForeignKey(ArticleSurvey, on_delete=models.CASCADE, related_name='survey_options')
option = models.CharField(max_length=255)
is_answer = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)

View File

@ -4,29 +4,38 @@ web_admin serializers file
from rest_framework import serializers
from web_admin.models import Article, ArticleCard, SurveyOption, ArticleSurvey
from web_admin.utils import pop_id
class ArticleCardSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
class Meta:
model = ArticleCard
fields = ('title', 'description')
fields = ('id', 'title', 'description')
class SurveyOptionSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
class Meta:
model = SurveyOption
fields = ('option', 'is_answer')
fields = ('id', 'option', 'is_answer')
class ArticleSurveySerializer(serializers.ModelSerializer):
options = SurveyOptionSerializer(many=True)
id = serializers.IntegerField(required=False)
survey_options = SurveyOptionSerializer(many=True)
class Meta:
model = ArticleSurvey
fields = ('question', 'points', 'options')
fields = ('id', 'question', 'points', 'survey_options')
class ArticleSerializer(serializers.ModelSerializer):
"""
serializer for article API
"""
article_cards = ArticleCardSerializer(many=True)
article_survey = ArticleSurveySerializer(many=True)
@ -35,21 +44,76 @@ class ArticleSerializer(serializers.ModelSerializer):
meta class
"""
model = Article
fields = ('title', 'description', 'article_cards', 'article_survey')
fields = ('id', 'title', 'description', 'article_cards', 'article_survey')
def create(self, validated_data):
"""
to create article.
ID in post data dict is for update api.
:param validated_data:
:return: success message
"""
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)
ArticleCard.objects.create(article=article, **card)
for survey in article_survey:
options = survey.pop('options')
survey = pop_id(survey)
options = survey.pop('survey_options')
survey_obj = ArticleSurvey.objects.create(article=article, **survey)
for option in options:
option = pop_id(option)
SurveyOption.objects.create(survey=survey_obj, **option)
return article
def update(self, instance, validated_data):
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()
# Update or create cards
for card_data in article_cards:
card_id = card_data.get('id', None)
if 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 = card_data.get('image', card.image)
card.save()
else:
card_data = pop_id(card_data)
ArticleCard.objects.create(article=instance, **card_data)
# Update or create survey sections
for survey_data in article_survey:
survey_id = survey_data.get('id', None)
options_data = survey_data.pop('survey_options')
if 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, **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)
return instance

13
web_admin/utils.py Normal file
View File

@ -0,0 +1,13 @@
"""
web_utils file
"""
def pop_id(data):
"""
to pop id, not in use
:param data:
:return: data
"""
data.pop('id') if 'id' in data else data
return data

View File

@ -7,17 +7,48 @@ from rest_framework.response import Response
from rest_framework import status
# local imports
from account.utils import custom_response, custom_error_response
from web_admin.models import Article
from web_admin.serializers import ArticleSerializer
class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin):
class ArticleViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.UpdateModelMixin,
mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.DestroyModelMixin):
serializer_class = ArticleSerializer
permission_classes = []
queryset = Article.objects.all()
queryset = Article.objects.prefetch_related('article_cards',
'article_survey',
'article_survey__survey_options')
def create(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({'message': "created"}, status=status.HTTP_201_CREATED)
return custom_response("created")
def update(self, request, *args, **kwargs):
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")
def list(self, request, *args, **kwargs):
# queryset = Article.objects.prefetch_related('article_cards',
# 'article_survey',
# 'article_survey__survey_options')
paginator = self.pagination_class()
paginated_queryset = paginator.paginate_queryset(self.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'])
serializer = self.serializer_class(queryset, many=True)
return custom_response(None, data=serializer.data)
def destroy(self, request, *args, **kwargs):
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)