Merge branch 'develop' into feature/elasticsearch-establishment-address
This commit is contained in:
commit
6e4e1b214d
50
apps/collection/migrations/0008_auto_20190916_1158.py
Normal file
50
apps/collection/migrations/0008_auto_20190916_1158.py
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-16 11:58
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
|
('collection', '0007_collection_image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='collection',
|
||||||
|
name='filters',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='collection',
|
||||||
|
name='selectors',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='collection',
|
||||||
|
name='targets',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='collectionitem',
|
||||||
|
name='item_ids',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='collectionitem',
|
||||||
|
name='item_type',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='collection',
|
||||||
|
name='collection_type',
|
||||||
|
field=models.PositiveSmallIntegerField(choices=[(0, 'Ordinary'), (1, 'Pop')], default=0, verbose_name='Collection type'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='collectionitem',
|
||||||
|
name='content_type',
|
||||||
|
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='collectionitem',
|
||||||
|
name='object_id',
|
||||||
|
field=models.PositiveIntegerField(blank=True, default=None, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
from django.contrib.postgres.fields import JSONField
|
from django.contrib.postgres.fields import JSONField
|
||||||
|
from django.contrib.contenttypes.fields import ContentType
|
||||||
|
from django.contrib.contenttypes import fields as generic
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
@ -40,6 +42,17 @@ class CollectionQuerySet(models.QuerySet):
|
||||||
|
|
||||||
class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin):
|
class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin):
|
||||||
"""Collection model."""
|
"""Collection model."""
|
||||||
|
ORDINARY = 0 # Ordinary collection
|
||||||
|
POP = 1 # POP collection
|
||||||
|
|
||||||
|
COLLECTION_TYPES = (
|
||||||
|
(ORDINARY, _('Ordinary')),
|
||||||
|
(POP, _('Pop')),
|
||||||
|
)
|
||||||
|
|
||||||
|
collection_type = models.PositiveSmallIntegerField(choices=COLLECTION_TYPES,
|
||||||
|
default=ORDINARY,
|
||||||
|
verbose_name=_('Collection type'))
|
||||||
image = models.ForeignKey(
|
image = models.ForeignKey(
|
||||||
'gallery.Image', null=True, blank=True, default=None,
|
'gallery.Image', null=True, blank=True, default=None,
|
||||||
verbose_name=_('Collection image'), on_delete=models.CASCADE)
|
verbose_name=_('Collection image'), on_delete=models.CASCADE)
|
||||||
|
|
@ -47,15 +60,6 @@ class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin):
|
||||||
default=False, verbose_name=_('Publish status'))
|
default=False, verbose_name=_('Publish status'))
|
||||||
on_top = models.BooleanField(
|
on_top = models.BooleanField(
|
||||||
default=False, verbose_name=_('Position on top'))
|
default=False, verbose_name=_('Position on top'))
|
||||||
filters = JSONField(
|
|
||||||
_('filters'), null=True, blank=True,
|
|
||||||
default=None, help_text='{"key":"value"}')
|
|
||||||
selectors = JSONField(
|
|
||||||
_('selectors'), null=True, blank=True,
|
|
||||||
default=None, help_text='{"key":"value"}')
|
|
||||||
targets = JSONField(
|
|
||||||
_('targets'), null=True, blank=True,
|
|
||||||
default=None, help_text='{"key":"value"}')
|
|
||||||
country = models.ForeignKey(
|
country = models.ForeignKey(
|
||||||
'location.Country', verbose_name=_('country'), on_delete=models.CASCADE)
|
'location.Country', verbose_name=_('country'), on_delete=models.CASCADE)
|
||||||
block_size = JSONField(
|
block_size = JSONField(
|
||||||
|
|
@ -86,10 +90,10 @@ class CollectionItem(ProjectBaseMixin):
|
||||||
"""CollectionItem model."""
|
"""CollectionItem model."""
|
||||||
collection = models.ForeignKey(
|
collection = models.ForeignKey(
|
||||||
Collection, verbose_name=_('collection'), on_delete=models.CASCADE)
|
Collection, verbose_name=_('collection'), on_delete=models.CASCADE)
|
||||||
item_type = models.IntegerField(verbose_name=_('item type identifier'))
|
content_type = models.ForeignKey(ContentType, default=None,
|
||||||
item_ids = JSONField(
|
null=True, blank=True, on_delete=models.CASCADE)
|
||||||
_('item_ids'), null=True, blank=True,
|
object_id = models.PositiveIntegerField(default=None, null=True, blank=True)
|
||||||
default=None, help_text='{"key":"value"}')
|
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||||
|
|
||||||
objects = CollectionItemQuerySet.as_manager()
|
objects = CollectionItemQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@ class CollectionSerializer(serializers.ModelSerializer):
|
||||||
# REQUEST
|
# REQUEST
|
||||||
start = serializers.DateTimeField(write_only=True)
|
start = serializers.DateTimeField(write_only=True)
|
||||||
end = serializers.DateTimeField(write_only=True)
|
end = serializers.DateTimeField(write_only=True)
|
||||||
filters = serializers.JSONField(write_only=True)
|
|
||||||
selectors = serializers.JSONField(write_only=True)
|
|
||||||
targets = serializers.JSONField(write_only=True)
|
|
||||||
country = serializers.PrimaryKeyRelatedField(
|
country = serializers.PrimaryKeyRelatedField(
|
||||||
queryset=location_models.Country.objects.all(),
|
queryset=location_models.Country.objects.all(),
|
||||||
write_only=True)
|
write_only=True)
|
||||||
|
|
@ -39,9 +36,6 @@ class CollectionSerializer(serializers.ModelSerializer):
|
||||||
'image_url',
|
'image_url',
|
||||||
'is_publish',
|
'is_publish',
|
||||||
'on_top',
|
'on_top',
|
||||||
'filters',
|
|
||||||
'selectors',
|
|
||||||
'targets',
|
|
||||||
'country',
|
'country',
|
||||||
'block_size',
|
'block_size',
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-16 11:48
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0018_socialnetwork'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='is_publish',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Publish status'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-17 10:46
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0018_socialnetwork'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='establishment',
|
||||||
|
name='transportation',
|
||||||
|
field=models.TextField(blank=True, default=None, null=True, verbose_name='Transportation'),
|
||||||
|
),
|
||||||
|
]
|
||||||
14
apps/establishment/migrations/0020_merge_20190917_1415.py
Normal file
14
apps/establishment/migrations/0020_merge_20190917_1415.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Generated by Django 2.2.4 on 2019-09-17 14:15
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0019_establishment_is_publish'),
|
||||||
|
('establishment', '0019_establishment_transportation'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
"""Establishment models."""
|
"""Establishment models."""
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
from django.contrib.gis.db.models.functions import Distance
|
||||||
|
|
||||||
|
from django.contrib.gis.measure import Distance as DistanceMeasure
|
||||||
|
from django.contrib.gis.geos import Point
|
||||||
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
|
||||||
|
|
@ -9,6 +12,8 @@ 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 collection.models import Collection
|
||||||
|
from review.models import Review
|
||||||
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField,
|
from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField,
|
||||||
TranslatedFieldsMixin, BaseAttributes)
|
TranslatedFieldsMixin, BaseAttributes)
|
||||||
|
|
||||||
|
|
@ -80,6 +85,109 @@ class EstablishmentQuerySet(models.QuerySet):
|
||||||
"""Return establishments by country code"""
|
"""Return establishments by country code"""
|
||||||
return self.filter(address__city__country__code=code)
|
return self.filter(address__city__country__code=code)
|
||||||
|
|
||||||
|
def published(self):
|
||||||
|
"""
|
||||||
|
Return QuerySet with published establishments.
|
||||||
|
"""
|
||||||
|
return self.filter(is_publish=True)
|
||||||
|
|
||||||
|
def annotate_distance(self, point: Point):
|
||||||
|
"""
|
||||||
|
Return QuerySet with annotated field - distance
|
||||||
|
Description:
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.annotate(distance=models.Value(
|
||||||
|
DistanceMeasure(Distance('address__coordinates', point, srid=4236)).m,
|
||||||
|
output_field=models.FloatField()))
|
||||||
|
|
||||||
|
def annotate_distance_mark(self):
|
||||||
|
"""
|
||||||
|
Return QuerySet with annotated field - distance_mark.
|
||||||
|
Required fields: distance.
|
||||||
|
Description:
|
||||||
|
If the radius of the establishments in QuerySet does not exceed 500 meters,
|
||||||
|
then distance_mark is set to 0.6, otherwise 0.
|
||||||
|
"""
|
||||||
|
return self.annotate(distance_mark=models.Case(
|
||||||
|
models.When(distance__lte=500,
|
||||||
|
then=0.6),
|
||||||
|
default=0,
|
||||||
|
output_field=models.FloatField()))
|
||||||
|
|
||||||
|
def annotate_intermediate_public_mark(self):
|
||||||
|
"""
|
||||||
|
Return QuerySet with annotated field - intermediate_public_mark.
|
||||||
|
Description:
|
||||||
|
If establishments in collection POP and its mark is null, then
|
||||||
|
intermediate_mark is set to 10;
|
||||||
|
"""
|
||||||
|
return self.annotate(intermediate_public_mark=models.Case(
|
||||||
|
models.When(
|
||||||
|
collections__collection__collection_type=Collection.POP,
|
||||||
|
public_mark__isnull=True,
|
||||||
|
then=10
|
||||||
|
),
|
||||||
|
default='public_mark',
|
||||||
|
output_field=models.FloatField()))
|
||||||
|
|
||||||
|
def annotate_additional_mark(self, public_mark: float):
|
||||||
|
"""
|
||||||
|
Return QuerySet with annotated field - additional_mark.
|
||||||
|
Required fields: intermediate_public_mark
|
||||||
|
Description:
|
||||||
|
IF
|
||||||
|
establishments public_mark + 3 > compared establishment public_mark
|
||||||
|
OR
|
||||||
|
establishments public_mark - 3 > compared establishment public_mark,
|
||||||
|
THEN
|
||||||
|
additional_mark is set to 0.4,
|
||||||
|
ELSE
|
||||||
|
set to 0.
|
||||||
|
"""
|
||||||
|
return self.annotate(additional_mark=models.Case(
|
||||||
|
models.When(
|
||||||
|
models.Q(intermediate_public_mark__lte=public_mark + 3) |
|
||||||
|
models.Q(intermediate_public_mark__lte=public_mark - 3),
|
||||||
|
then=0.4),
|
||||||
|
default=0,
|
||||||
|
output_field=models.FloatField()))
|
||||||
|
|
||||||
|
def annotate_total_mark(self):
|
||||||
|
"""
|
||||||
|
Return QuerySet with annotated field - total_mark.
|
||||||
|
Required fields: distance_mark, additional_mark.
|
||||||
|
Fields
|
||||||
|
Description:
|
||||||
|
Annotated field is obtained by formula:
|
||||||
|
(distance + additional marks) * intermediate_public_mark.
|
||||||
|
"""
|
||||||
|
return self.annotate(
|
||||||
|
total_mark=(models.F('distance_mark') + models.F('additional_mark')) *
|
||||||
|
models.F('intermediate_public_mark'))
|
||||||
|
|
||||||
|
def similar(self, establishment_pk: int):
|
||||||
|
"""
|
||||||
|
Return QuerySet with objects that similar to Establishment.
|
||||||
|
:param establishment_pk: integer
|
||||||
|
"""
|
||||||
|
establishment_qs = Establishment.objects.filter(pk=establishment_pk)
|
||||||
|
if establishment_qs.exists():
|
||||||
|
establishment = establishment_qs.first()
|
||||||
|
return self.exclude(pk=establishment_pk) \
|
||||||
|
.filter(is_publish=True,
|
||||||
|
image__isnull=False,
|
||||||
|
reviews__isnull=False,
|
||||||
|
reviews__status=Review.READY,
|
||||||
|
public_mark__gte=10) \
|
||||||
|
.annotate_distance(point=establishment.address.coordinates) \
|
||||||
|
.annotate_distance_mark() \
|
||||||
|
.annotate_intermediate_public_mark() \
|
||||||
|
.annotate_additional_mark(public_mark=establishment.public_mark) \
|
||||||
|
.annotate_total_mark()
|
||||||
|
else:
|
||||||
|
return self.none()
|
||||||
|
|
||||||
def prefetch_actual_employees(self):
|
def prefetch_actual_employees(self):
|
||||||
"""Prefetch actual employees."""
|
"""Prefetch actual employees."""
|
||||||
return self.prefetch_related(
|
return self.prefetch_related(
|
||||||
|
|
@ -153,10 +261,14 @@ class Establishment(ProjectBaseMixin, ImageMixin, TranslatedFieldsMixin):
|
||||||
verbose_name=_('Lafourchette URL'))
|
verbose_name=_('Lafourchette URL'))
|
||||||
booking = models.URLField(blank=True, null=True, default=None,
|
booking = models.URLField(blank=True, null=True, default=None,
|
||||||
verbose_name=_('Booking URL'))
|
verbose_name=_('Booking URL'))
|
||||||
|
is_publish = models.BooleanField(default=False, verbose_name=_('Publish status'))
|
||||||
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')
|
comments = generic.GenericRelation(to='comment.Comment')
|
||||||
|
transportation = models.TextField(blank=True, null=True, default=None,
|
||||||
|
verbose_name=_('Transportation'))
|
||||||
|
collections = generic.GenericRelation(to='collection.CollectionItem')
|
||||||
|
|
||||||
objects = EstablishmentQuerySet.as_manager()
|
objects = EstablishmentQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
|
||||||
'menu',
|
'menu',
|
||||||
'best_price_menu',
|
'best_price_menu',
|
||||||
'best_price_carte',
|
'best_price_carte',
|
||||||
|
'transportation',
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_review(self, obj):
|
def get_review(self, obj):
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ urlpatterns = [
|
||||||
path('', views.EstablishmentListView.as_view(), name='list'),
|
path('', views.EstablishmentListView.as_view(), name='list'),
|
||||||
path('tags/', views.EstablishmentTagListView.as_view(), name='tags'),
|
path('tags/', views.EstablishmentTagListView.as_view(), name='tags'),
|
||||||
path('<int:pk>/', views.EstablishmentRetrieveView.as_view(), name='detail'),
|
path('<int:pk>/', views.EstablishmentRetrieveView.as_view(), name='detail'),
|
||||||
|
path('<int:pk>/similar/', views.EstablishmentSimilarListView.as_view(), name='similar'),
|
||||||
path('<int:pk>/comments/', views.EstablishmentCommentListView.as_view(), name='list-comments'),
|
path('<int:pk>/comments/', views.EstablishmentCommentListView.as_view(), name='list-comments'),
|
||||||
path('<int:pk>/comments/create/', views.EstablishmentCommentCreateView.as_view(),
|
path('<int:pk>/comments/create/', views.EstablishmentCommentCreateView.as_view(),
|
||||||
name='create-comment'),
|
name='create-comment'),
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,5 @@ class EstablishmentMixin:
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Overrided method 'get_queryset'."""
|
"""Overrided method 'get_queryset'."""
|
||||||
return models.Establishment.objects.all().prefetch_actual_employees()
|
return models.Establishment.objects.published() \
|
||||||
|
.prefetch_actual_employees()
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from utils.views import JWTGenericViewMixin
|
||||||
from establishment.views import EstablishmentMixin
|
from establishment.views import EstablishmentMixin
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentListView(EstablishmentMixin, JWTGenericViewMixin, generics.ListAPIView):
|
class EstablishmentListView(EstablishmentMixin, generics.ListAPIView):
|
||||||
"""Resource for getting a list of establishments."""
|
"""Resource for getting a list of establishments."""
|
||||||
serializer_class = serializers.EstablishmentListSerializer
|
serializer_class = serializers.EstablishmentListSerializer
|
||||||
filter_class = filters.EstablishmentFilter
|
filter_class = filters.EstablishmentFilter
|
||||||
|
|
@ -19,10 +19,21 @@ class EstablishmentListView(EstablishmentMixin, JWTGenericViewMixin, generics.Li
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Overridden method 'get_queryset'."""
|
"""Overridden method 'get_queryset'."""
|
||||||
qs = super(EstablishmentListView, self).get_queryset()
|
qs = super(EstablishmentListView, self).get_queryset()
|
||||||
return qs.by_country_code(code=self.request.country_code)\
|
return qs.by_country_code(code=self.request.country_code) \
|
||||||
.annotate_in_favorites(user=self.request.user)
|
.annotate_in_favorites(user=self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentSimilarListView(EstablishmentListView):
|
||||||
|
"""Resource for getting a list of establishments."""
|
||||||
|
serializer_class = serializers.EstablishmentListSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Override get_queryset method"""
|
||||||
|
qs = super().get_queryset()
|
||||||
|
return qs.similar(establishment_pk=self.kwargs.get('pk'))\
|
||||||
|
.order_by('-total_mark')[:13]
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentRetrieveView(EstablishmentMixin, JWTGenericViewMixin, generics.RetrieveAPIView):
|
class EstablishmentRetrieveView(EstablishmentMixin, JWTGenericViewMixin, generics.RetrieveAPIView):
|
||||||
"""Resource for getting a establishment."""
|
"""Resource for getting a establishment."""
|
||||||
serializer_class = serializers.EstablishmentDetailSerializer
|
serializer_class = serializers.EstablishmentDetailSerializer
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class CityAdmin(admin.ModelAdmin):
|
||||||
class AddressAdmin(admin.OSMGeoAdmin):
|
class AddressAdmin(admin.OSMGeoAdmin):
|
||||||
"""Address admin."""
|
"""Address admin."""
|
||||||
list_display = ('__str__', 'geo_lon', 'geo_lat')
|
list_display = ('__str__', 'geo_lon', 'geo_lat')
|
||||||
readonly_fields = ['geo_lon', 'geo_lat',]
|
readonly_fields = ['geo_lon', 'geo_lat', ]
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(_('Main'), {
|
(_('Main'), {
|
||||||
'fields': ['street_name_1', 'street_name_2', 'number']
|
'fields': ['street_name_1', 'street_name_2', 'number']
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ class RegionSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class CitySerializer(serializers.ModelSerializer):
|
class CitySerializer(serializers.ModelSerializer):
|
||||||
"""City serializer."""
|
"""City serializer."""
|
||||||
country = CountrySerializer()
|
|
||||||
region = RegionSerializer()
|
region = RegionSerializer()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -48,7 +47,6 @@ class CitySerializer(serializers.ModelSerializer):
|
||||||
'name',
|
'name',
|
||||||
'code',
|
'code',
|
||||||
'region',
|
'region',
|
||||||
'country',
|
|
||||||
'postal_code',
|
'postal_code',
|
||||||
'is_island',
|
'is_island',
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
# @admin.register(models.Review)
|
"""Admin page for app Review"""
|
||||||
# class ReviewAdminModel(admin.ModelAdmin):
|
from . import models
|
||||||
# """Admin model for model Review."""
|
from django.contrib import admin
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(models.Review)
|
||||||
|
class ReviewAdminModel(admin.ModelAdmin):
|
||||||
|
"""Admin model for model Review."""
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,4 @@ ELASTICSEARCH_INDEX_NAMES = {
|
||||||
sentry_sdk.init(
|
sentry_sdk.init(
|
||||||
dsn="https://35d9bb789677410ab84a822831c6314f@sentry.io/1729093",
|
dsn="https://35d9bb789677410ab84a822831c6314f@sentry.io/1729093",
|
||||||
integrations=[DjangoIntegration()]
|
integrations=[DjangoIntegration()]
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user