slugs for news & establishments
This commit is contained in:
parent
fb93231650
commit
1ce71fdcdc
34
apps/collection/migrations/0012_collection_slug.py
Normal file
34
apps/collection/migrations/0012_collection_slug.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Generated by Django 2.2.4 on 2019-09-23 12:55
|
||||
|
||||
from django.db import migrations
|
||||
import django_extensions.db.fields
|
||||
|
||||
from collection.models import Collection
|
||||
|
||||
|
||||
def migrate_data_forward(apps, schema_editor):
|
||||
for instance in Collection.objects.all():
|
||||
print("Generating slug for %s" % instance)
|
||||
instance.save() # Will trigger slug update
|
||||
|
||||
def migrate_data_backward(apps, schema_editor):
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('collection', '0011_auto_20190920_1059'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='collection',
|
||||
name='slug',
|
||||
field=django_extensions.db.fields.AutoSlugField(blank=True, editable=True, populate_from=['name', 'pk'], db_index=True, verbose_name='Collection slug'),
|
||||
),
|
||||
migrations.RunPython(
|
||||
migrate_data_forward,
|
||||
migrate_data_backward,
|
||||
),
|
||||
]
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
from django.contrib.postgres.fields import JSONField
|
||||
from django.contrib.contenttypes.fields import ContentType
|
||||
from django_extensions.db.fields import AutoSlugField
|
||||
|
||||
from utils.models import TJSONField
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
|
@ -67,6 +69,8 @@ class Collection(ProjectBaseMixin, CollectionNameMixin, CollectionDateMixin,
|
|||
description = TJSONField(
|
||||
_('description'), null=True, blank=True,
|
||||
default=None, help_text='{"en-GB":"some text"}')
|
||||
slug = AutoSlugField(max_length=50, db_index=True, populate_from=['name', 'pk'],
|
||||
verbose_name=_('Collection slug'), editable=True)
|
||||
|
||||
objects = CollectionQuerySet.as_manager()
|
||||
|
||||
|
|
|
|||
33
apps/establishment/migrations/0029_establishment_slug.py
Normal file
33
apps/establishment/migrations/0029_establishment_slug.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 2.2.4 on 2019-09-23 12:55
|
||||
|
||||
from django.db import migrations
|
||||
import django_extensions.db.fields
|
||||
|
||||
from establishment.models import Establishment
|
||||
|
||||
|
||||
def migrate_data_forward(apps, schema_editor):
|
||||
for instance in Establishment.objects.all():
|
||||
print("Generating slug for %s" % instance)
|
||||
instance.save() # Will trigger slug update
|
||||
|
||||
def migrate_data_backward(apps, schema_editor):
|
||||
pass
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('establishment', '0028_auto_20190920_1205'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='establishment',
|
||||
name='slug',
|
||||
field=django_extensions.db.fields.AutoSlugField(blank=True, editable=True, populate_from=['name'], db_index=True, verbose_name='Establishment slug'),
|
||||
),
|
||||
migrations.RunPython(
|
||||
migrate_data_forward,
|
||||
migrate_data_backward,
|
||||
),
|
||||
]
|
||||
|
|
@ -9,6 +9,7 @@ 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 django_extensions.db.fields import AutoSlugField
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
|
||||
from location.models import Address
|
||||
|
|
@ -166,15 +167,15 @@ class EstablishmentQuerySet(models.QuerySet):
|
|||
total_mark=(models.F('distance_mark') + models.F('additional_mark')) *
|
||||
models.F('intermediate_public_mark'))
|
||||
|
||||
def similar(self, establishment_pk: int):
|
||||
def similar(self, establishment_slug: str):
|
||||
"""
|
||||
Return QuerySet with objects that similar to Establishment.
|
||||
:param establishment_pk: integer
|
||||
:param establishment_slug: str Establishment slug
|
||||
"""
|
||||
establishment_qs = Establishment.objects.filter(pk=establishment_pk)
|
||||
establishment_qs = Establishment.objects.filter(slug=establishment_slug)
|
||||
if establishment_qs.exists():
|
||||
establishment = establishment_qs.first()
|
||||
return self.exclude(pk=establishment_pk) \
|
||||
return self.exclude(slug=establishment_slug) \
|
||||
.filter(is_publish=True,
|
||||
image_url__isnull=False,
|
||||
reviews__isnull=False,
|
||||
|
|
@ -277,6 +278,8 @@ class Establishment(ProjectBaseMixin, URLImageMixin, TranslatedFieldsMixin):
|
|||
verbose_name=_('Collections'))
|
||||
preview_image_url = models.URLField(verbose_name=_('Preview image URL path'),
|
||||
blank=True, null=True, default=None)
|
||||
slug = AutoSlugField(db_index=True, max_length=50, populate_from=['name'],
|
||||
verbose_name=_('Establishment slug'), editable=True)
|
||||
|
||||
awards = generic.GenericRelation(to='main.Award')
|
||||
tags = generic.GenericRelation(to='main.MetaDataContent')
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class EstablishmentListCreateSerializer(EstablishmentBaseSerializer):
|
|||
phones = ContactPhonesSerializer(read_only=True, many=True, )
|
||||
emails = ContactEmailsSerializer(read_only=True, many=True, )
|
||||
socials = SocialNetworkRelatedSerializers(read_only=True, many=True, )
|
||||
slug = serializers.SlugField(allow_blank=True)
|
||||
|
||||
class Meta:
|
||||
model = models.Establishment
|
||||
|
|
@ -35,6 +36,7 @@ class EstablishmentListCreateSerializer(EstablishmentBaseSerializer):
|
|||
'type',
|
||||
'socials',
|
||||
'image_url',
|
||||
'slug',
|
||||
# TODO: check in admin filters
|
||||
'is_publish'
|
||||
]
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer):
|
|||
subtypes = EstablishmentSubTypeSerializer(many=True)
|
||||
address = AddressSerializer()
|
||||
tags = MetaDataContentSerializer(many=True)
|
||||
slug = serializers.SlugField(allow_blank=True)
|
||||
|
||||
class Meta:
|
||||
"""Meta class."""
|
||||
|
|
@ -162,6 +163,7 @@ class EstablishmentBaseSerializer(serializers.ModelSerializer):
|
|||
'subtypes',
|
||||
'address',
|
||||
'tags',
|
||||
'slug',
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -197,6 +199,8 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
|
|||
best_price_menu = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
|
||||
best_price_carte = serializers.DecimalField(max_digits=14, decimal_places=2, read_only=True)
|
||||
|
||||
slug = serializers.SlugField(read_only=True)
|
||||
|
||||
in_favorites = serializers.SerializerMethodField()
|
||||
|
||||
image = serializers.URLField(source='image_url')
|
||||
|
|
@ -224,6 +228,7 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
|
|||
'best_price_menu',
|
||||
'best_price_carte',
|
||||
'transportation',
|
||||
'slug',
|
||||
]
|
||||
|
||||
def get_review(self, obj):
|
||||
|
|
@ -261,8 +266,8 @@ class EstablishmentCommentCreateSerializer(comment_serializers.CommentSerializer
|
|||
def validate(self, attrs):
|
||||
"""Override validate method"""
|
||||
# Check establishment object
|
||||
establishment_id = self.context.get('request').parser_context.get('kwargs').get('pk')
|
||||
establishment_qs = models.Establishment.objects.filter(id=establishment_id)
|
||||
establishment_slug = self.context.get('request').parser_context.get('kwargs').get('slug')
|
||||
establishment_qs = models.Establishment.objects.filter(slug=establishment_slug)
|
||||
if not establishment_qs.exists():
|
||||
raise serializers.ValidationError({'detail': _('Establishment not found.')})
|
||||
attrs['establishment'] = establishment_qs.first()
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ app_name = 'establishment'
|
|||
urlpatterns = [
|
||||
path('', views.EstablishmentListView.as_view(), name='list'),
|
||||
path('tags/', views.EstablishmentTagListView.as_view(), name='tags'),
|
||||
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/create/', views.EstablishmentCommentCreateView.as_view(),
|
||||
path('<slug:slug>/', views.EstablishmentRetrieveView.as_view(), name='detail'),
|
||||
path('<slug:slug>/similar/', views.EstablishmentSimilarListView.as_view(), name='similar'),
|
||||
path('<slug:slug>/comments/', views.EstablishmentCommentListView.as_view(), name='list-comments'),
|
||||
path('<slug:slug>/comments/create/', views.EstablishmentCommentCreateView.as_view(),
|
||||
name='create-comment'),
|
||||
path('<int:pk>/comments/<int:comment_id>/', views.EstablishmentCommentRUDView.as_view(),
|
||||
path('<slug:slug>/comments/<int:comment_id>/', views.EstablishmentCommentRUDView.as_view(),
|
||||
name='rud-comment'),
|
||||
path('<int:pk>/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(),
|
||||
path('<slug:slug>/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(),
|
||||
name='add-to-favorites')
|
||||
]
|
||||
|
|
|
|||
|
|
@ -30,11 +30,12 @@ class EstablishmentSimilarListView(EstablishmentListView):
|
|||
|
||||
def get_queryset(self):
|
||||
"""Override get_queryset method"""
|
||||
return super().get_queryset().similar(establishment_pk=self.kwargs.get('pk'))\
|
||||
return super().get_queryset().similar(establishment_slug=self.kwargs.get('slug'))\
|
||||
.order_by('-total_mark')[:13]
|
||||
|
||||
class EstablishmentRetrieveView(EstablishmentMixin, generics.RetrieveAPIView):
|
||||
"""Resource for getting a establishment."""
|
||||
lookup_field = 'slug'
|
||||
serializer_class = serializers.EstablishmentDetailSerializer
|
||||
|
||||
|
||||
|
|
@ -48,6 +49,7 @@ class EstablishmentTypeListView(generics.ListAPIView):
|
|||
|
||||
class EstablishmentCommentCreateView(generics.CreateAPIView):
|
||||
"""View for create new comment."""
|
||||
lookup_field = 'slug'
|
||||
serializer_class = serializers.EstablishmentCommentCreateSerializer
|
||||
queryset = comment_models.Comment.objects.all()
|
||||
|
||||
|
|
@ -59,9 +61,11 @@ class EstablishmentCommentListView(generics.ListAPIView):
|
|||
|
||||
def get_queryset(self):
|
||||
"""Override get_queryset method"""
|
||||
|
||||
establishment = get_object_or_404(models.Establishment, slug=self.kwargs['slug'])
|
||||
return comment_models.Comment.objects.by_content_type(app_label='establishment',
|
||||
model='establishment')\
|
||||
.by_object_id(object_id=self.kwargs.get('pk'))\
|
||||
.by_object_id(object_id=establishment.pk)\
|
||||
.order_by('-created')
|
||||
|
||||
|
||||
|
|
@ -77,7 +81,7 @@ class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView):
|
|||
queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
establishment_obj = get_object_or_404(queryset,
|
||||
pk=self.kwargs['pk'])
|
||||
slug=self.kwargs['slug'])
|
||||
comment_obj = get_object_or_404(establishment_obj.comments.by_user(self.request.user),
|
||||
pk=self.kwargs['comment_id'])
|
||||
|
||||
|
|
@ -90,15 +94,18 @@ class EstablishmentCommentRUDView(generics.RetrieveUpdateDestroyAPIView):
|
|||
class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.DestroyAPIView):
|
||||
"""View for create/destroy establishment from favorites."""
|
||||
serializer_class = serializers.EstablishmentFavoritesCreateSerializer
|
||||
lookup_field = 'slug'
|
||||
|
||||
def get_object(self):
|
||||
"""
|
||||
Returns the object the view is displaying.
|
||||
"""
|
||||
establishment_obj = get_object_or_404(models.Establishment,
|
||||
slug=self.kwargs['slug'])
|
||||
obj = get_object_or_404(
|
||||
self.request.user.favorites.by_content_type(app_label='establishment',
|
||||
model='establishment')
|
||||
.by_object_id(object_id=self.kwargs['pk']))
|
||||
.by_object_id(object_id=establishment_obj.pk))
|
||||
# May raise a permission denied
|
||||
self.check_object_permissions(self.request, obj)
|
||||
return obj
|
||||
|
|
|
|||
33
apps/news/migrations/0010_news_slug.py
Normal file
33
apps/news/migrations/0010_news_slug.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 2.2.4 on 2019-09-23 12:55
|
||||
|
||||
from django.db import migrations
|
||||
import django_extensions.db.fields
|
||||
|
||||
from news.models import News
|
||||
|
||||
def migrate_data_forward(apps, schema_editor):
|
||||
for instance in News.objects.all():
|
||||
print("Generating slug for %s" % instance)
|
||||
instance.save() # Will trigger slug update
|
||||
|
||||
def migrate_data_backward(apps, schema_editor):
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('news', '0009_auto_20190901_1032'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='news',
|
||||
name='slug',
|
||||
field=django_extensions.db.fields.AutoSlugField(blank=True, editable=True, populate_from=['title'], db_index=True, verbose_name='News slug'),
|
||||
),
|
||||
migrations.RunPython(
|
||||
migrate_data_forward,
|
||||
migrate_data_backward,
|
||||
),
|
||||
]
|
||||
|
|
@ -3,6 +3,7 @@ from django.db import models
|
|||
from django.contrib.contenttypes import fields as generic
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_extensions.db.fields import AutoSlugField
|
||||
from rest_framework.reverse import reverse
|
||||
from utils.models import BaseAttributes, TJSONField, TranslatedFieldsMixin
|
||||
|
||||
|
|
@ -49,6 +50,10 @@ class NewsQuerySet(models.QuerySet):
|
|||
class News(BaseAttributes, TranslatedFieldsMixin):
|
||||
"""News model."""
|
||||
|
||||
image = models.ForeignKey(
|
||||
'gallery.Image', null=True, blank=True, default=None,
|
||||
verbose_name=_('News image'), on_delete=models.CASCADE)
|
||||
|
||||
news_type = models.ForeignKey(NewsType, on_delete=models.PROTECT,
|
||||
verbose_name=_('news type'))
|
||||
title = TJSONField(blank=True, null=True, default=None,
|
||||
|
|
@ -63,6 +68,8 @@ class News(BaseAttributes, TranslatedFieldsMixin):
|
|||
start = models.DateTimeField(verbose_name=_('Start'))
|
||||
end = models.DateTimeField(blank=True, null=True, default=None,
|
||||
verbose_name=_('End'))
|
||||
slug = AutoSlugField(db_index=True, max_length=50, populate_from=['title'],
|
||||
verbose_name=_('News slug'), editable=True,)
|
||||
playlist = models.IntegerField(_('playlist'))
|
||||
is_publish = models.BooleanField(default=False,
|
||||
verbose_name=_('Publish status'))
|
||||
|
|
@ -93,8 +100,8 @@ class News(BaseAttributes, TranslatedFieldsMixin):
|
|||
verbose_name_plural = _('news')
|
||||
|
||||
def __str__(self):
|
||||
return f'news: {self.id}'
|
||||
return f'news: {self.slug}'
|
||||
|
||||
@property
|
||||
def web_url(self):
|
||||
return reverse('web:news:rud', kwargs={'pk': self.pk})
|
||||
return reverse('web:news:rud', kwargs={'slug': self.slug})
|
||||
|
|
|
|||
0
apps/news/serializers/common.py
Normal file
0
apps/news/serializers/common.py
Normal file
|
|
@ -6,6 +6,6 @@ app_name = 'news'
|
|||
|
||||
urlpatterns = [
|
||||
path('', views.NewsListView.as_view(), name='list'),
|
||||
path('<int:pk>/', views.NewsDetailView.as_view(), name='rud'),
|
||||
path('<slug:slug>/', views.NewsDetailView.as_view(), name='rud'),
|
||||
path('types/', views.NewsTypeListView.as_view(), name='type'),
|
||||
]
|
||||
|
|
|
|||
0
apps/news/views/common.py
Normal file
0
apps/news/views/common.py
Normal file
|
|
@ -13,7 +13,7 @@ class NewsDocumentViewSet(BaseDocumentViewSet):
|
|||
"""News document ViewSet."""
|
||||
|
||||
document = NewsDocument
|
||||
lookup_field = 'id'
|
||||
lookup_field = 'slug'
|
||||
pagination_class = PageNumberPagination
|
||||
permission_classes = (permissions.AllowAny,)
|
||||
serializer_class = serializers.NewsDocumentSerializer
|
||||
|
|
@ -39,7 +39,7 @@ class EstablishmentDocumentViewSet(BaseDocumentViewSet):
|
|||
"""Establishment document ViewSet."""
|
||||
|
||||
document = EstablishmentDocument
|
||||
lookup_field = 'id'
|
||||
lookup_field = 'slug'
|
||||
pagination_class = PageNumberPagination
|
||||
permission_classes = (permissions.AllowAny,)
|
||||
serializer_class = serializers.EstablishmentDocumentSerializer
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user