fix comments

This commit is contained in:
Anatoly 2020-01-15 22:31:17 +03:00
parent 4b45cab976
commit f86357e041
10 changed files with 124 additions and 40 deletions

View File

@ -0,0 +1,18 @@
from django.core.management.base import BaseCommand
from comment.models import Comment
from tqdm import tqdm
class Command(BaseCommand):
help = 'Add status to comments from is_publish_ flag.'
def handle(self, *args, **kwargs):
to_update = []
for comment in tqdm(Comment.objects.all()):
if hasattr(comment, 'is_publish') and hasattr(comment, 'status'):
comment.status = Comment.PUBLISHED if comment.is_publish else Comment.WAITING
to_update.append(comment)
Comment.objects.bulk_update(to_update, ('status', ))
self.stdout.write(self.style.WARNING(f'Updated {len(to_update)} objects.'))

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2.7 on 2020-01-15 13:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('comment', '0007_comment_site'),
]
operations = [
migrations.AddField(
model_name='comment',
name='status',
field=models.PositiveSmallIntegerField(choices=[(0, 'Waiting'), (1, 'Published'), (2, 'Rejected'), (3, 'Deleted')], default=0, verbose_name='status'),
),
]

View File

@ -16,6 +16,10 @@ class CommentQuerySet(ContentTypeQuerySetMixin):
"""Return comments by author""" """Return comments by author"""
return self.filter(user=user) return self.filter(user=user)
def published(self):
"""Return only published comments."""
return self.filter(status=self.model.PUBLISHED)
def annotate_is_mine_status(self, user): def annotate_is_mine_status(self, user):
"""Annotate belonging status""" """Annotate belonging status"""
return self.annotate(is_mine=models.Case( return self.annotate(is_mine=models.Case(
@ -27,16 +31,48 @@ class CommentQuerySet(ContentTypeQuerySetMixin):
output_field=models.BooleanField() output_field=models.BooleanField()
)) ))
def public(self, user):
"""
Return QuerySet by rules:
1 With status PUBLISHED
2 With status WAITING if comment author is <user>
"""
qs = self.published()
if isinstance(user, User):
waiting_ids = list(
self.filter(status=self.model.WAITING, user=user)
.values_list('id', flat=True))
published_ids = list(qs.values_list('id', flat=True))
waiting_ids.extend(published_ids)
qs = self.filter(id__in=tuple(waiting_ids))
return qs
class Comment(ProjectBaseMixin): class Comment(ProjectBaseMixin):
"""Comment model.""" """Comment model."""
WAITING = 0
PUBLISHED = 1
REJECTED = 2
DELETED = 3
STATUSES = (
(WAITING, _('Waiting')),
(PUBLISHED, _('Published')),
(REJECTED, _('Rejected')),
(DELETED, _('Deleted')),
)
text = models.TextField(verbose_name=_('Comment text')) text = models.TextField(verbose_name=_('Comment text'))
mark = models.PositiveIntegerField(blank=True, null=True, default=None, verbose_name=_('Mark')) mark = models.PositiveIntegerField(blank=True, null=True, default=None, verbose_name=_('Mark'))
user = models.ForeignKey('account.User', related_name='comments', on_delete=models.CASCADE, verbose_name=_('User')) user = models.ForeignKey('account.User', related_name='comments', on_delete=models.CASCADE, verbose_name=_('User'))
old_id = models.IntegerField(null=True, blank=True, default=None) old_id = models.IntegerField(null=True, blank=True, default=None)
is_publish = models.BooleanField(default=False, verbose_name=_('Publish status')) is_publish = models.BooleanField(default=False, verbose_name=_('Publish status'))
status = models.PositiveSmallIntegerField(choices=STATUSES,
default=WAITING,
verbose_name=_('status'))
site = models.ForeignKey('main.SiteSettings', blank=True, null=True, site = models.ForeignKey('main.SiteSettings', blank=True, null=True,
on_delete=models.SET_NULL, verbose_name=_('site')) on_delete=models.SET_NULL, verbose_name=_('site'))
content_type = models.ForeignKey(generic.ContentType, on_delete=models.CASCADE) content_type = models.ForeignKey(generic.ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id') content_object = generic.GenericForeignKey('content_type', 'object_id')

View File

@ -4,13 +4,15 @@ from rest_framework import serializers
from comment.models import Comment from comment.models import Comment
class CommentSerializer(serializers.ModelSerializer): class CommentBaseSerializer(serializers.ModelSerializer):
"""Comment serializer""" """Comment serializer"""
nickname = serializers.CharField(read_only=True, nickname = serializers.CharField(read_only=True,
source='user.username') source='user.username')
is_mine = serializers.BooleanField(read_only=True) is_mine = serializers.BooleanField(read_only=True)
profile_pic = serializers.URLField(read_only=True, profile_pic = serializers.URLField(read_only=True,
source='user.cropped_image_url') source='user.cropped_image_url')
status_display = serializers.CharField(read_only=True,
source='get_status_display')
class Meta: class Meta:
"""Serializer for model Comment""" """Serializer for model Comment"""
@ -23,19 +25,10 @@ class CommentSerializer(serializers.ModelSerializer):
'text', 'text',
'mark', 'mark',
'nickname', 'nickname',
'profile_pic'
]
class CommentRUDSerializer(CommentSerializer):
"""Retrieve/Update/Destroy comment serializer."""
class Meta(CommentSerializer.Meta):
"""Meta class."""
fields = [
'id',
'created',
'text',
'mark',
'nickname',
'profile_pic', 'profile_pic',
'status',
'status_display',
] ]
extra_kwargs = {
'status': {'read_only': True},
}

View File

@ -20,6 +20,7 @@ def transfer_comments():
'mark', 'mark',
'establishment_id', 'establishment_id',
'account_id', 'account_id',
'state',
) )
serialized_data = CommentSerializer(data=list(queryset.values()), many=True) serialized_data = CommentSerializer(data=list(queryset.values()), many=True)

View File

@ -450,7 +450,7 @@ class EstablishmentDetailSerializer(EstablishmentBaseSerializer):
class MobileEstablishmentDetailSerializer(EstablishmentDetailSerializer): class MobileEstablishmentDetailSerializer(EstablishmentDetailSerializer):
"""Serializer for Establishment model for mobiles.""" """Serializer for Establishment model for mobiles."""
last_comment = comment_serializers.CommentRUDSerializer(allow_null=True) last_comment = comment_serializers.CommentBaseSerializer(allow_null=True)
class Meta(EstablishmentDetailSerializer.Meta): class Meta(EstablishmentDetailSerializer.Meta):
"""Meta class.""" """Meta class."""
@ -482,13 +482,11 @@ class EstablishmentSimilarSerializer(EstablishmentBaseSerializer):
] ]
class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer): class EstablishmentCommentBaseSerializer(comment_serializers.CommentBaseSerializer):
"""Create comment serializer""" """Create comment serializer"""
mark = serializers.IntegerField()
class Meta: class Meta(comment_serializers.CommentBaseSerializer.Meta):
"""Serializer for model Comment""" """Serializer for model Comment"""
model = comment_models.Comment
fields = [ fields = [
'id', 'id',
'created', 'created',
@ -496,8 +494,14 @@ class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer
'mark', 'mark',
'nickname', 'nickname',
'profile_pic', 'profile_pic',
'status',
'status_display',
] ]
class EstablishmentCommentCreateSerializer(EstablishmentCommentBaseSerializer):
"""Extended EstablishmentCommentBaseSerializer."""
def validate(self, attrs): def validate(self, attrs):
"""Override validate method""" """Override validate method"""
# Check establishment object # Check establishment object
@ -517,7 +521,7 @@ class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer
return super().create(validated_data) return super().create(validated_data)
class EstablishmentCommentRUDSerializer(comment_serializers.CommentSerializer): class EstablishmentCommentRUDSerializer(comment_serializers.CommentBaseSerializer):
"""Retrieve/Update/Destroy comment serializer.""" """Retrieve/Update/Destroy comment serializer."""
class Meta: class Meta:

View File

@ -5,7 +5,6 @@ from django.shortcuts import get_object_or_404
from rest_framework import generics, permissions from rest_framework import generics, permissions
from comment import models as comment_models from comment import models as comment_models
from comment.serializers import CommentRUDSerializer
from establishment import filters, models, serializers from establishment import filters, models, serializers
from main import methods from main import methods
from utils.pagination import PortionPagination from utils.pagination import PortionPagination
@ -188,18 +187,17 @@ class EstablishmentCommentListView(generics.ListAPIView):
"""View for return list of establishment comments.""" """View for return list of establishment comments."""
permission_classes = (permissions.AllowAny,) permission_classes = (permissions.AllowAny,)
serializer_class = serializers.EstablishmentCommentCreateSerializer serializer_class = serializers.EstablishmentCommentBaseSerializer
def get_queryset(self): def get_queryset(self):
"""Override get_queryset method""" """Override get_queryset method"""
establishment = get_object_or_404(models.Establishment, slug=self.kwargs['slug']) establishment = get_object_or_404(models.Establishment, slug=self.kwargs['slug'])
return establishment.comments.order_by('-created') return establishment.comments.public(self.request.user).order_by('-created')
class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView): class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView):
"""View for retrieve/update/destroy establishment comment.""" """View for retrieve/update/destroy establishment comment."""
serializer_class = CommentRUDSerializer serializer_class = serializers.EstablishmentCommentBaseSerializer
queryset = models.Establishment.objects.all() queryset = models.Establishment.objects.all()
def get_object(self): def get_object(self):

View File

@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from comment.models import Comment from comment.models import Comment
from comment.serializers import CommentSerializer from comment.serializers import CommentBaseSerializer
from establishment.serializers import EstablishmentProductShortSerializer from establishment.serializers import EstablishmentProductShortSerializer
from establishment.serializers.common import _EstablishmentAddressShortSerializer from establishment.serializers.common import _EstablishmentAddressShortSerializer
from location.serializers import WineOriginRegionBaseSerializer,\ from location.serializers import WineOriginRegionBaseSerializer,\
@ -200,13 +200,11 @@ class ProductFavoritesCreateSerializer(FavoritesCreateSerializer):
return super().create(validated_data) return super().create(validated_data)
class ProductCommentCreateSerializer(CommentSerializer): class ProductCommentBaseSerializer(CommentBaseSerializer):
"""Create comment serializer""" """Create comment serializer."""
mark = serializers.IntegerField()
class Meta: class Meta(CommentBaseSerializer.Meta):
"""Serializer for model Comment""" """Serializer for model Comment"""
model = Comment
fields = [ fields = [
'id', 'id',
'created', 'created',
@ -214,8 +212,14 @@ class ProductCommentCreateSerializer(CommentSerializer):
'mark', 'mark',
'nickname', 'nickname',
'profile_pic', 'profile_pic',
'status',
'status_display',
] ]
class ProductCommentCreateSerializer(ProductCommentBaseSerializer):
"""Serializer for creating comments for product."""
def validate(self, attrs): def validate(self, attrs):
"""Override validate method""" """Override validate method"""
# Check product object # Check product object

View File

@ -4,12 +4,10 @@ from django.shortcuts import get_object_or_404
from rest_framework import generics, permissions from rest_framework import generics, permissions
from comment.models import Comment from comment.models import Comment
from comment.serializers import CommentRUDSerializer from comment.serializers import CommentBaseSerializer
from product import filters, serializers from product import filters, serializers
from product.models import Product, ProductType from product.models import Product, ProductType
from utils.views import FavoritesCreateDestroyMixinView from utils.views import FavoritesCreateDestroyMixinView
from utils.pagination import PortionPagination
from django.conf import settings
class ProductBaseView(generics.GenericAPIView): class ProductBaseView(generics.GenericAPIView):
@ -81,17 +79,17 @@ class ProductCommentListView(generics.ListAPIView):
"""View for return list of product comments.""" """View for return list of product comments."""
permission_classes = (permissions.AllowAny,) permission_classes = (permissions.AllowAny,)
serializer_class = serializers.ProductCommentCreateSerializer serializer_class = serializers.ProductCommentBaseSerializer
def get_queryset(self): def get_queryset(self):
"""Override get_queryset method""" """Override get_queryset method"""
product = get_object_or_404(Product, slug=self.kwargs['slug']) product = get_object_or_404(Product, slug=self.kwargs['slug'])
return product.comments.order_by('-created') return product.comments.public(self.request.user).order_by('-created')
class ProductCommentRUDView(generics.RetrieveUpdateDestroyAPIView): class ProductCommentRUDView(generics.RetrieveUpdateDestroyAPIView):
"""View for retrieve/update/destroy product comment.""" """View for retrieve/update/destroy product comment."""
serializer_class = CommentRUDSerializer serializer_class = serializers.ProductCommentBaseSerializer
queryset = Product.objects.all() queryset = Product.objects.all()
def get_object(self): def get_object(self):

View File

@ -10,6 +10,7 @@ class CommentSerializer(serializers.Serializer):
mark = serializers.DecimalField(max_digits=4, decimal_places=2, allow_null=True) mark = serializers.DecimalField(max_digits=4, decimal_places=2, allow_null=True)
account_id = serializers.IntegerField() account_id = serializers.IntegerField()
establishment_id = serializers.CharField() establishment_id = serializers.CharField()
state = serializers.CharField()
def validate(self, data): def validate(self, data):
data.update({ data.update({
@ -18,14 +19,18 @@ class CommentSerializer(serializers.Serializer):
'mark': self.get_mark(data), 'mark': self.get_mark(data),
'content_object': self.get_content_object(data), 'content_object': self.get_content_object(data),
'user': self.get_account(data), 'user': self.get_account(data),
'status': self.get_status(data),
}) })
data.pop('establishment_id') data.pop('establishment_id')
data.pop('account_id') data.pop('account_id')
data.pop('state')
return data return data
def create(self, validated_data): def create(self, validated_data):
try: try:
return Comment.objects.create(**validated_data) comment, _ = Comment.objects.get_or_create(old_id=validated_data.get('old_id'),
defaults=validated_data)
return comment
except Exception as e: except Exception as e:
raise ValueError(f"Error creating comment with {validated_data}: {e}") raise ValueError(f"Error creating comment with {validated_data}: {e}")
@ -48,3 +53,12 @@ class CommentSerializer(serializers.Serializer):
if not data['mark']: if not data['mark']:
return None return None
return data['mark'] * -1 if data['mark'] < 0 else data['mark'] return data['mark'] * -1 if data['mark'] < 0 else data['mark']
@staticmethod
def get_status(data):
if data.get('state'):
state = data.get('state')
if state == 'published':
return Comment.PUBLISHED
elif state == 'deleted':
return Comment.DELETED