replace comment model from establishment app, added new app comment
This commit is contained in:
parent
cfc2d512ed
commit
605c81b33c
0
apps/comment/__init__.py
Normal file
0
apps/comment/__init__.py
Normal file
8
apps/comment/admin.py
Normal file
8
apps/comment/admin.py
Normal 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
8
apps/comment/apps.py
Normal 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')
|
||||
36
apps/comment/migrations/0001_initial.py
Normal file
36
apps/comment/migrations/0001_initial.py
Normal 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',
|
||||
},
|
||||
),
|
||||
]
|
||||
0
apps/comment/migrations/__init__.py
Normal file
0
apps/comment/migrations/__init__.py
Normal file
51
apps/comment/models.py
Normal file
51
apps/comment/models.py
Normal 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)
|
||||
0
apps/comment/serializers/__init__.py
Normal file
0
apps/comment/serializers/__init__.py
Normal file
60
apps/comment/serializers/common.py
Normal file
60
apps/comment/serializers/common.py
Normal 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)
|
||||
0
apps/comment/serializers/mobile.py
Normal file
0
apps/comment/serializers/mobile.py
Normal file
1
apps/comment/serializers/web.py
Normal file
1
apps/comment/serializers/web.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
"""Serializers for app comment."""
|
||||
1
apps/comment/tests.py
Normal file
1
apps/comment/tests.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Create your tests here.
|
||||
0
apps/comment/urls/__init__.py
Normal file
0
apps/comment/urls/__init__.py
Normal file
12
apps/comment/urls/common.py
Normal file
12
apps/comment/urls/common.py
Normal 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'),
|
||||
]
|
||||
9
apps/comment/urls/mobile.py
Normal file
9
apps/comment/urls/mobile.py
Normal 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
9
apps/comment/urls/web.py
Normal 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
|
||||
0
apps/comment/views/__init__.py
Normal file
0
apps/comment/views/__init__.py
Normal file
34
apps/comment/views/common.py
Normal file
34
apps/comment/views/common.py
Normal 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)
|
||||
0
apps/comment/views/mobile.py
Normal file
0
apps/comment/views/mobile.py
Normal file
0
apps/comment/views/web.py
Normal file
0
apps/comment/views/web.py
Normal 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."""
|
||||
|
|
|
|||
16
apps/establishment/migrations/0015_delete_comment.py
Normal file
16
apps/establishment/migrations/0015_delete_comment.py
Normal 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',
|
||||
),
|
||||
]
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ PROJECT_APPS = [
|
|||
'configuration.apps.ConfigurationConfig',
|
||||
'timetable.apps.TimetableConfig',
|
||||
'review.apps.ReviewConfig',
|
||||
'comment.apps.CommentConfig',
|
||||
]
|
||||
|
||||
EXTERNAL_APPS = [
|
||||
|
|
|
|||
|
|
@ -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')),
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user