create, delete, get favorite news
This commit is contained in:
parent
28471686be
commit
d853960d2e
|
|
@ -10,4 +10,6 @@ urlpatterns = [
|
||||||
name='establishment-list'),
|
name='establishment-list'),
|
||||||
path('products/', views.FavoritesProductListView.as_view(),
|
path('products/', views.FavoritesProductListView.as_view(),
|
||||||
name='product-list'),
|
name='product-list'),
|
||||||
|
path('news/', views.FavoritesNewsListView.as_view(),
|
||||||
|
name='news-list'),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ from rest_framework import generics
|
||||||
from establishment.models import Establishment
|
from establishment.models import Establishment
|
||||||
from establishment.filters import EstablishmentFilter
|
from establishment.filters import EstablishmentFilter
|
||||||
from establishment.serializers import EstablishmentBaseSerializer
|
from establishment.serializers import EstablishmentBaseSerializer
|
||||||
|
from news.filters import NewsListFilterSet
|
||||||
|
from news.models import News
|
||||||
|
from news.serializers import NewsBaseSerializer
|
||||||
from product.models import Product
|
from product.models import Product
|
||||||
from product.serializers import ProductBaseSerializer
|
from product.serializers import ProductBaseSerializer
|
||||||
from product.filters import ProductFilterSet
|
from product.filters import ProductFilterSet
|
||||||
|
|
@ -25,8 +28,8 @@ class FavoritesEstablishmentListView(generics.ListAPIView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Override get_queryset method"""
|
"""Override get_queryset method"""
|
||||||
return Establishment.objects.filter(favorites__user=self.request.user)\
|
return Establishment.objects.filter(favorites__user=self.request.user) \
|
||||||
.order_by('-favorites')
|
.order_by('-favorites')
|
||||||
|
|
||||||
|
|
||||||
class FavoritesProductListView(generics.ListAPIView):
|
class FavoritesProductListView(generics.ListAPIView):
|
||||||
|
|
@ -37,5 +40,16 @@ class FavoritesProductListView(generics.ListAPIView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Override get_queryset method"""
|
"""Override get_queryset method"""
|
||||||
return Product.objects.filter(favorites__user=self.request.user)\
|
return Product.objects.filter(favorites__user=self.request.user) \
|
||||||
.order_by('-favorites')
|
.order_by('-favorites')
|
||||||
|
|
||||||
|
|
||||||
|
class FavoritesNewsListView(generics.ListAPIView):
|
||||||
|
"""List views for news in favorites."""
|
||||||
|
|
||||||
|
serializer_class = NewsBaseSerializer
|
||||||
|
filter_class = NewsListFilterSet
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Override get_queryset method"""
|
||||||
|
return News.objects.filter(favorites__user=self.request.user).order_by('-favorites')
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ class News(BaseAttributes, TranslatedFieldsMixin):
|
||||||
verbose_name=_('Tags'))
|
verbose_name=_('Tags'))
|
||||||
gallery = models.ManyToManyField('gallery.Image', through='news.NewsGallery')
|
gallery = models.ManyToManyField('gallery.Image', through='news.NewsGallery')
|
||||||
ratings = generic.GenericRelation(Rating)
|
ratings = generic.GenericRelation(Rating)
|
||||||
|
favorites = generic.GenericRelation(to='favorites.Favorites')
|
||||||
agenda = models.ForeignKey('news.Agenda', blank=True, null=True,
|
agenda = models.ForeignKey('news.Agenda', blank=True, null=True,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
verbose_name=_('agenda'))
|
verbose_name=_('agenda'))
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ from location import models as location_models
|
||||||
from location.serializers import CountrySimpleSerializer, AddressBaseSerializer
|
from location.serializers import CountrySimpleSerializer, AddressBaseSerializer
|
||||||
from news import models
|
from news import models
|
||||||
from tag.serializers import TagBaseSerializer
|
from tag.serializers import TagBaseSerializer
|
||||||
from utils.serializers import TranslatedField, ProjectModelSerializer
|
from utils import exceptions as utils_exceptions
|
||||||
|
from utils.serializers import TranslatedField, ProjectModelSerializer, FavoritesCreateSerializer
|
||||||
|
|
||||||
|
|
||||||
class AgendaSerializer(ProjectModelSerializer):
|
class AgendaSerializer(ProjectModelSerializer):
|
||||||
|
|
@ -293,3 +294,33 @@ class NewsBackOfficeGallerySerializer(serializers.ModelSerializer):
|
||||||
attrs['image'] = image
|
attrs['image'] = image
|
||||||
|
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
|
class NewsFavoritesCreateSerializer(FavoritesCreateSerializer):
|
||||||
|
"""Serializer to favorite object w/ model News."""
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
"""Overridden validate method"""
|
||||||
|
# Check establishment object
|
||||||
|
news_qs = models.News.objects.filter(slug=self.slug)
|
||||||
|
|
||||||
|
# Check establishment obj by slug from lookup_kwarg
|
||||||
|
if not news_qs.exists():
|
||||||
|
raise serializers.ValidationError({'detail': _('Object not found.')})
|
||||||
|
else:
|
||||||
|
news = news_qs.first()
|
||||||
|
|
||||||
|
# Check existence in favorites
|
||||||
|
if news.favorites.filter(user=self.user).exists():
|
||||||
|
raise utils_exceptions.FavoritesError()
|
||||||
|
|
||||||
|
attrs['news'] = news
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
def create(self, validated_data, *args, **kwargs):
|
||||||
|
"""Overridden create method"""
|
||||||
|
validated_data.update({
|
||||||
|
'user': self.user,
|
||||||
|
'content_object': validated_data.pop('news')
|
||||||
|
})
|
||||||
|
return super().create(validated_data)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ from news.models import NewsType, News
|
||||||
from account.models import User, Role, UserRole
|
from account.models import User, Role, UserRole
|
||||||
from translation.models import Language
|
from translation.models import Language
|
||||||
from location.models import Country
|
from location.models import Country
|
||||||
|
|
||||||
|
|
||||||
# Create your tests here.
|
# Create your tests here.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -67,7 +69,7 @@ class NewsTestCase(BaseTestCase):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
def test_news_post(self):
|
def test_news_post(self):
|
||||||
test_news ={
|
test_news = {
|
||||||
"title": {"en-GB": "Test news POST"},
|
"title": {"en-GB": "Test news POST"},
|
||||||
"news_type_id": self.test_news_type.id,
|
"news_type_id": self.test_news_type.id,
|
||||||
"description": {"en-GB": "Description test news"},
|
"description": {"en-GB": "Description test news"},
|
||||||
|
|
@ -108,9 +110,21 @@ class NewsTestCase(BaseTestCase):
|
||||||
'description': {"en-GB": "Description test news!"},
|
'description': {"en-GB": "Description test news!"},
|
||||||
'slug': self.test_news.slug,
|
'slug': self.test_news.slug,
|
||||||
'start': self.test_news.start,
|
'start': self.test_news.start,
|
||||||
'news_type_id':self.test_news.news_type_id,
|
'news_type_id': self.test_news.news_type_id,
|
||||||
'country_id': self.country_ru.id
|
'country_id': self.country_ru.id
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.put(url, data=data, format='json')
|
response = self.client.put(url, data=data, format='json')
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
def test_web_favorite_create_delete(self):
|
||||||
|
data = {
|
||||||
|
"user": self.user.id,
|
||||||
|
"object_id": self.test_news.id
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.client.post(f'/api/web/news/slug/{self.test_news.slug}/favorites/', data=data)
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
|
|
||||||
|
response = self.client.delete(f'/api/web/news/slug/{self.test_news.slug}/favorites/', format='json')
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,5 @@ urlpatterns = [
|
||||||
path('', views.NewsListView.as_view(), name='list'),
|
path('', views.NewsListView.as_view(), name='list'),
|
||||||
path('types/', views.NewsTypeListView.as_view(), name='type'),
|
path('types/', views.NewsTypeListView.as_view(), name='type'),
|
||||||
path('slug/<slug:slug>/', views.NewsDetailView.as_view(), name='rud'),
|
path('slug/<slug:slug>/', views.NewsDetailView.as_view(), name='rud'),
|
||||||
|
path('slug/<slug:slug>/favorites/', views.NewsFavoritesCreateDestroyView.as_view(), name='create-destroy-favorites')
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ class NewsMixinView:
|
||||||
def get_queryset(self, *args, **kwargs):
|
def get_queryset(self, *args, **kwargs):
|
||||||
"""Override get_queryset method."""
|
"""Override get_queryset method."""
|
||||||
qs = models.News.objects.published() \
|
qs = models.News.objects.published() \
|
||||||
.with_base_related() \
|
.with_base_related() \
|
||||||
.order_by('-is_highlighted', '-created')
|
.order_by('-is_highlighted', '-created')
|
||||||
country_code = self.request.country_code
|
country_code = self.request.country_code
|
||||||
if country_code:
|
if country_code:
|
||||||
qs = qs.by_country_code(country_code)
|
qs = qs.by_country_code(country_code)
|
||||||
|
|
@ -51,7 +51,7 @@ class NewsTypeListView(generics.ListAPIView):
|
||||||
"""NewsType list view."""
|
"""NewsType list view."""
|
||||||
|
|
||||||
pagination_class = None
|
pagination_class = None
|
||||||
permission_classes = (permissions.AllowAny, )
|
permission_classes = (permissions.AllowAny,)
|
||||||
queryset = models.NewsType.objects.all()
|
queryset = models.NewsType.objects.all()
|
||||||
serializer_class = serializers.NewsTypeSerializer
|
serializer_class = serializers.NewsTypeSerializer
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ class NewsBackOfficeLCView(NewsBackOfficeMixinView,
|
||||||
|
|
||||||
serializer_class = serializers.NewsBackOfficeBaseSerializer
|
serializer_class = serializers.NewsBackOfficeBaseSerializer
|
||||||
create_serializers_class = serializers.NewsBackOfficeDetailSerializer
|
create_serializers_class = serializers.NewsBackOfficeDetailSerializer
|
||||||
permission_classes = [IsCountryAdmin|IsContentPageManager]
|
permission_classes = [IsCountryAdmin | IsContentPageManager]
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
"""Override serializer class."""
|
"""Override serializer class."""
|
||||||
|
|
@ -146,9 +146,26 @@ class NewsBackOfficeRUDView(NewsBackOfficeMixinView,
|
||||||
"""Resource for detailed information about news for back-office users."""
|
"""Resource for detailed information about news for back-office users."""
|
||||||
|
|
||||||
serializer_class = serializers.NewsBackOfficeDetailSerializer
|
serializer_class = serializers.NewsBackOfficeDetailSerializer
|
||||||
permission_classes = [IsCountryAdmin|IsContentPageManager]
|
permission_classes = [IsCountryAdmin | IsContentPageManager]
|
||||||
|
|
||||||
def get(self, request, pk, *args, **kwargs):
|
def get(self, request, pk, *args, **kwargs):
|
||||||
add_rating(remote_addr=request.META.get('REMOTE_ADDR'),
|
add_rating(remote_addr=request.META.get('REMOTE_ADDR'),
|
||||||
pk=pk, model='news', app_label='news')
|
pk=pk, model='news', app_label='news')
|
||||||
return self.retrieve(request, *args, **kwargs)
|
return self.retrieve(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class NewsFavoritesCreateDestroyView(generics.CreateAPIView, generics.DestroyAPIView):
|
||||||
|
"""View for create/destroy news from favorites."""
|
||||||
|
|
||||||
|
serializer_class = serializers.NewsFavoritesCreateSerializer
|
||||||
|
lookup_field = 'slug'
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
"""
|
||||||
|
Returns the object the view is displaying.
|
||||||
|
"""
|
||||||
|
news = get_object_or_404(models.News, slug=self.kwargs['slug'])
|
||||||
|
favorites = get_object_or_404(news.favorites.filter(user=self.request.user))
|
||||||
|
# May raise a permission denied
|
||||||
|
self.check_object_permissions(self.request, favorites)
|
||||||
|
return favorites
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user