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."""
|
"""Establishment admin conf."""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.contenttypes.admin import GenericTabularInline
|
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 establishment import models
|
||||||
from main.models import Award, MetaDataContent
|
from main.models import Award, MetaDataContent
|
||||||
from review import models as review_models
|
from review import models as review_models
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.EstablishmentType)
|
@admin.register(models.EstablishmentType)
|
||||||
|
|
@ -44,13 +46,18 @@ class ReviewInline(GenericTabularInline):
|
||||||
extra = 0
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
|
class CommentInline(GenericTabularInline):
|
||||||
|
model = Comment
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.Establishment)
|
@admin.register(models.Establishment)
|
||||||
class EstablishmentAdmin(admin.ModelAdmin):
|
class EstablishmentAdmin(admin.ModelAdmin):
|
||||||
"""Establishment admin."""
|
"""Establishment admin."""
|
||||||
inlines = [
|
inlines = [
|
||||||
AwardInline, MetaDataContentInline,
|
AwardInline, MetaDataContentInline,
|
||||||
ContactPhoneInline, ContactEmailInline,
|
ContactPhoneInline, ContactEmailInline,
|
||||||
ReviewInline]
|
ReviewInline, CommentInline]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.EstablishmentSchedule)
|
@admin.register(models.EstablishmentSchedule)
|
||||||
|
|
@ -58,11 +65,6 @@ class EstablishmentSchedule(admin.ModelAdmin):
|
||||||
"""Establishment schedule"""
|
"""Establishment schedule"""
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.Comment)
|
|
||||||
class EstablishmentComment(admin.ModelAdmin):
|
|
||||||
"""Establishment comments."""
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.Position)
|
@admin.register(models.Position)
|
||||||
class PositionAdmin(admin.ModelAdmin):
|
class PositionAdmin(admin.ModelAdmin):
|
||||||
"""Position admin."""
|
"""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."""
|
"""Establishment models."""
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
from django.contrib.contenttypes import fields as generic
|
from django.contrib.contenttypes import fields as generic
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from phonenumber_field.modelfields import PhoneNumberField
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
|
|
||||||
from location.models import Address
|
from location.models import Address
|
||||||
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField,
|
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField,
|
||||||
TranslatedFieldsMixin, BaseAttributes)
|
TranslatedFieldsMixin, BaseAttributes)
|
||||||
|
|
@ -129,6 +131,7 @@ class Establishment(ProjectBaseMixin, ImageMixin, TranslatedFieldsMixin):
|
||||||
awards = generic.GenericRelation(to='main.Award')
|
awards = generic.GenericRelation(to='main.Award')
|
||||||
tags = generic.GenericRelation(to='main.MetaDataContent')
|
tags = generic.GenericRelation(to='main.MetaDataContent')
|
||||||
reviews = generic.GenericRelation(to='review.Review')
|
reviews = generic.GenericRelation(to='review.Review')
|
||||||
|
comments = generic.GenericRelation(to='comment.Comment')
|
||||||
|
|
||||||
objects = EstablishmentQuerySet.as_manager()
|
objects = EstablishmentQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
@ -345,38 +348,3 @@ class Menu(TranslatedFieldsMixin, BaseAttributes):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('menu')
|
verbose_name = _('menu')
|
||||||
verbose_name_plural = _('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."""
|
"""Establishment serializers."""
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from comment.serializers.common import CommentSerializer
|
||||||
from establishment import models
|
from establishment import models
|
||||||
from location.serializers import AddressSerializer
|
from location.serializers import AddressSerializer
|
||||||
from main.serializers import MetaDataContentSerializer, AwardSerializer, CurrencySerializer
|
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):
|
class EstablishmentEmployeeSerializer(serializers.ModelSerializer):
|
||||||
"""Serializer for actual employees."""
|
"""Serializer for actual employees."""
|
||||||
|
|
||||||
|
|
@ -154,7 +138,8 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
phones = ContactPhonesSerializer(read_only=True, many=True, )
|
phones = ContactPhonesSerializer(read_only=True, many=True, )
|
||||||
emails = ContactEmailsSerializer(read_only=True, many=True, )
|
emails = ContactEmailsSerializer(read_only=True, many=True, )
|
||||||
reviews = ReviewSerializer(source='reviews.last', allow_null=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',
|
employees = EstablishmentEmployeeSerializer(source='actual_establishment_employees',
|
||||||
many=True)
|
many=True)
|
||||||
menu = MenuSerializers(source='menu_set', many=True, read_only=True)
|
menu = MenuSerializers(source='menu_set', many=True, read_only=True)
|
||||||
|
|
@ -198,6 +183,15 @@ class EstablishmentSerializer(serializers.ModelSerializer):
|
||||||
'best_price_carte'
|
'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):
|
def get_preview_image(self, obj):
|
||||||
"""Get preview image"""
|
"""Get preview image"""
|
||||||
return obj.get_full_image_url(request=self.context.get('request'),
|
return obj.get_full_image_url(request=self.context.get('request'),
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ PROJECT_APPS = [
|
||||||
'configuration.apps.ConfigurationConfig',
|
'configuration.apps.ConfigurationConfig',
|
||||||
'timetable.apps.TimetableConfig',
|
'timetable.apps.TimetableConfig',
|
||||||
'review.apps.ReviewConfig',
|
'review.apps.ReviewConfig',
|
||||||
|
'comment.apps.CommentConfig',
|
||||||
]
|
]
|
||||||
|
|
||||||
EXTERNAL_APPS = [
|
EXTERNAL_APPS = [
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,5 @@ urlpatterns = [
|
||||||
path('location/', include('location.urls')),
|
path('location/', include('location.urls')),
|
||||||
path('main/', include('main.urls')),
|
path('main/', include('main.urls')),
|
||||||
path('translation/', include('translation.urls')),
|
path('translation/', include('translation.urls')),
|
||||||
|
path('comments/', include('comment.urls.web')),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user