replace comment model from establishment app, added new app comment

This commit is contained in:
Anatoly 2019-09-04 18:47:06 +03:00
parent cfc2d512ed
commit 605c81b33c
25 changed files with 271 additions and 60 deletions

0
apps/comment/__init__.py Normal file
View File

8
apps/comment/admin.py Normal file
View File

@ -0,0 +1,8 @@
from django.contrib import admin
from . import models
@admin.register(models.Comment)
class CommentModelAdmin(admin.ModelAdmin):
"""Model admin for model Comment"""

8
apps/comment/apps.py Normal file
View File

@ -0,0 +1,8 @@
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class CommentConfig(AppConfig):
name = 'comment'
verbose_name = _('comment')
verbose_name_plural = _('comments')

View File

@ -0,0 +1,36 @@
# Generated by Django 2.2.4 on 2019-09-04 14:03
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Comment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='Date created')),
('modified', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('text', models.TextField(verbose_name='Comment text')),
('mark', models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='Mark')),
('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to=settings.AUTH_USER_MODEL, verbose_name='User')),
],
options={
'verbose_name': 'Comment',
'verbose_name_plural': 'Comments',
},
),
]

View File

51
apps/comment/models.py Normal file
View File

@ -0,0 +1,51 @@
"""Models for app comment."""
from django.contrib.contenttypes import fields as generic
from django.db import models
from django.utils.translation import gettext_lazy as _
from account.models import User
from utils.models import ProjectBaseMixin
class CommentQuerySet(models.QuerySet):
"""QuerySets for Comment model."""
def by_user(self, user: User):
"""Return comments by author"""
return self.filter(user=user)
def annotate_is_mine_status(self, user):
"""Annotate belonging status"""
return self.annotate(is_mine=models.Case(
models.When(
models.Q(user=user),
then=True
),
default=False,
output_field=models.BooleanField(default=False)
))
class Comment(ProjectBaseMixin):
"""Comment model."""
text = models.TextField(verbose_name=_('Comment text'))
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'))
content_type = models.ForeignKey(generic.ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
objects = CommentQuerySet.as_manager()
class Meta:
"""Meta class"""
verbose_name = _('Comment')
verbose_name_plural = _('Comments')
def __str__(self):
"""String representation"""
return str(self.user)

View File

View File

@ -0,0 +1,60 @@
"""Common serializers for app comment."""
from rest_framework import serializers
from comment import models
from establishment.models import Establishment
class CommentBaseMixin(serializers.Serializer):
"""Comment base serializer mixin"""
# RESPONSE
nickname = serializers.CharField(read_only=True,
source='user.username')
profile_pic = serializers.ImageField(read_only=True,
source='user.image')
class CommentSerializer(CommentBaseMixin, serializers.ModelSerializer):
"""Comment serializer"""
is_mine = serializers.BooleanField(read_only=True)
class Meta:
"""Serializer for model Comment"""
model = models.Comment
fields = [
'id',
'user_id',
'is_mine',
'created',
'text',
'mark',
'nickname',
'profile_pic'
]
class EstablishmentCommentCreateSerializer(CommentSerializer):
"""Create comment serializer"""
mark = serializers.IntegerField()
establishment_id = serializers.PrimaryKeyRelatedField(queryset=Establishment.objects.all(),
source='content_object',
write_only=True)
class Meta:
"""Serializer for model Comment"""
model = models.Comment
fields = [
'created',
'text',
'mark',
'nickname',
'profile_pic',
'establishment_id',
]
def create(self, validated_data):
"""Override create method"""
validated_data.update({
'user': self.context.get('request').user
})
return super().create(validated_data)

View File

View File

@ -0,0 +1 @@
"""Serializers for app comment."""

1
apps/comment/tests.py Normal file
View File

@ -0,0 +1 @@
# Create your tests here.

View File

View File

@ -0,0 +1,12 @@
"""Comment urlpaths."""
from django.urls import path
from comment.views import common as views
app_name = 'comment'
urlpatterns = [
path('', views.CommentListView.as_view(), name='comment-list'),
path('create/', views.CommentCreateView.as_view(), name='comment-create'),
path('<int:pk>/', views.CommentRUD.as_view(), name='comment-rud'),
]

View File

@ -0,0 +1,9 @@
"""Mobile urlpaths."""
from comment.urls.common import urlpatterns as common_urlpatterns
app_name = 'comment'
urlpatterns_api = []
urlpatterns = common_urlpatterns + \
urlpatterns_api

9
apps/comment/urls/web.py Normal file
View File

@ -0,0 +1,9 @@
"""Web urlpaths."""
from comment.urls.common import urlpatterns as common_urlpatterns
app_name = 'comment'
urlpatterns_api = []
urlpatterns = common_urlpatterns + \
urlpatterns_api

View File

View File

@ -0,0 +1,34 @@
"""Views for app comment."""
from rest_framework import generics
from rest_framework.permissions import AllowAny
from comment.models import Comment
from comment.serializers import common as serializers
class CommentViewMixin:
"""Mixin for Comment views"""
queryset = Comment.objects.order_by('-created')
serializer_class = serializers.CommentSerializer
class CommentListView(CommentViewMixin, generics.ListAPIView):
"""View for retrieving list of comments."""
permission_classes = (AllowAny, )
def get_queryset(self):
"""Override get_queryset method."""
return self.queryset.annotate_is_mine_status(user=self.request.user)
class CommentCreateView(CommentViewMixin, generics.CreateAPIView):
"""View for create new comment."""
serializer_class = serializers.EstablishmentCommentCreateSerializer
class CommentRUD(CommentViewMixin, generics.RetrieveUpdateDestroyAPIView):
"""View for retrieve/update/destroy view."""
def get_queryset(self):
"""Override get_queryset method."""
return self.queryset.by_user(self.request.user)

View File

View File

View File

@ -1,10 +1,12 @@
"""Establishment admin conf."""
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from django.utils.translation import gettext_lazy as _
from comment.models import Comment
from establishment import models
from main.models import Award, MetaDataContent
from review import models as review_models
from django.utils.translation import gettext_lazy as _
@admin.register(models.EstablishmentType)
@ -44,13 +46,18 @@ class ReviewInline(GenericTabularInline):
extra = 0
class CommentInline(GenericTabularInline):
model = Comment
extra = 0
@admin.register(models.Establishment)
class EstablishmentAdmin(admin.ModelAdmin):
"""Establishment admin."""
inlines = [
AwardInline, MetaDataContentInline,
ContactPhoneInline, ContactEmailInline,
ReviewInline]
ReviewInline, CommentInline]
@admin.register(models.EstablishmentSchedule)
@ -58,11 +65,6 @@ class EstablishmentSchedule(admin.ModelAdmin):
"""Establishment schedule"""
@admin.register(models.Comment)
class EstablishmentComment(admin.ModelAdmin):
"""Establishment comments."""
@admin.register(models.Position)
class PositionAdmin(admin.ModelAdmin):
"""Position admin."""

View File

@ -0,0 +1,16 @@
# Generated by Django 2.2.4 on 2019-09-04 13:12
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('establishment', '0014_establishment_website'),
]
operations = [
migrations.DeleteModel(
name='Comment',
),
]

View File

@ -1,11 +1,13 @@
"""Establishment models."""
from functools import reduce
from django.contrib.contenttypes import fields as generic
from django.core.exceptions import ValidationError
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from location.models import Address
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField,
TranslatedFieldsMixin, BaseAttributes)
@ -129,6 +131,7 @@ class Establishment(ProjectBaseMixin, ImageMixin, TranslatedFieldsMixin):
awards = generic.GenericRelation(to='main.Award')
tags = generic.GenericRelation(to='main.MetaDataContent')
reviews = generic.GenericRelation(to='review.Review')
comments = generic.GenericRelation(to='comment.Comment')
objects = EstablishmentQuerySet.as_manager()
@ -345,38 +348,3 @@ class Menu(TranslatedFieldsMixin, BaseAttributes):
class Meta:
verbose_name = _('menu')
verbose_name_plural = _('menu')
class CommentQuerySet(models.QuerySet):
"""QuerySets for Comment model."""
def by_author(self, author):
"""Return comments by author"""
return self.filter(author=author)
class Comment(ProjectBaseMixin):
"""Comment model."""
text = models.TextField(verbose_name=_('Comment text'))
mark = models.PositiveIntegerField(blank=True, null=True,
default=None,
verbose_name=_('Mark'))
author = models.ForeignKey('account.User',
related_name='comments',
on_delete=models.CASCADE,
verbose_name=_('Author'))
establishment = models.ForeignKey(Establishment,
related_name='comments',
on_delete=models.CASCADE,
verbose_name=_('Establishment'))
objects = CommentQuerySet.as_manager()
class Meta:
"""Meta class"""
verbose_name = _('Comment')
verbose_name_plural = _('Comments')
def __str__(self):
"""String representation"""
return str(self.author)

View File

@ -1,6 +1,7 @@
"""Establishment serializers."""
from rest_framework import serializers
from comment.serializers.common import CommentSerializer
from establishment import models
from location.serializers import AddressSerializer
from main.serializers import MetaDataContentSerializer, AwardSerializer, CurrencySerializer
@ -106,23 +107,6 @@ class ReviewSerializer(serializers.ModelSerializer):
)
class CommentSerializer(serializers.ModelSerializer):
"""Comment serializer"""
nickname = serializers.CharField(source='author.username')
profile_pic = serializers.ImageField(source='author.image')
class Meta:
"""Serializer for model Comment"""
model = models.Comment
fields = (
'created',
'text',
'mark',
'nickname',
'profile_pic'
)
class EstablishmentEmployeeSerializer(serializers.ModelSerializer):
"""Serializer for actual employees."""
@ -154,7 +138,8 @@ class EstablishmentSerializer(serializers.ModelSerializer):
phones = ContactPhonesSerializer(read_only=True, many=True, )
emails = ContactEmailsSerializer(read_only=True, many=True, )
reviews = ReviewSerializer(source='reviews.last', allow_null=True)
comments = CommentSerializer(many=True, allow_null=True)
# comments = CommentSerializer(many=True, allow_null=True)
comments = serializers.SerializerMethodField()
employees = EstablishmentEmployeeSerializer(source='actual_establishment_employees',
many=True)
menu = MenuSerializers(source='menu_set', many=True, read_only=True)
@ -198,6 +183,15 @@ class EstablishmentSerializer(serializers.ModelSerializer):
'best_price_carte'
)
def get_comments(self, obj):
"""Serializer method for comment field"""
request = self.context.get('request')
if request.user.is_authenticated:
return CommentSerializer(obj.comments.all().annotate_is_mine_status(user=request.user),
many=True).data
else:
return CommentSerializer(obj.comments.all(), many=True).data
def get_preview_image(self, obj):
"""Get preview image"""
return obj.get_full_image_url(request=self.context.get('request'),

View File

@ -67,6 +67,7 @@ PROJECT_APPS = [
'configuration.apps.ConfigurationConfig',
'timetable.apps.TimetableConfig',
'review.apps.ReviewConfig',
'comment.apps.CommentConfig',
]
EXTERNAL_APPS = [

View File

@ -28,4 +28,5 @@ urlpatterns = [
path('location/', include('location.urls')),
path('main/', include('main.urls')),
path('translation/', include('translation.urls')),
path('comments/', include('comment.urls.web')),
]