gm-148: finish
This commit is contained in:
parent
7f79ce8945
commit
501b8833ed
41
apps/gallery/migrations/0002_auto_20190930_0714.py
Normal file
41
apps/gallery/migrations/0002_auto_20190930_0714.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Generated by Django 2.2.4 on 2019-09-30 07:14
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import easy_thumbnails.fields
|
||||
import utils.methods
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gallery', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='image',
|
||||
name='orientation',
|
||||
field=models.PositiveSmallIntegerField(blank=True, choices=[(0, 'Horizontal'), (1, 'Vertical')], default=None, null=True, verbose_name='image orientation'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='image',
|
||||
name='parent',
|
||||
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_DEFAULT, related_name='parent_image', to='gallery.Image', verbose_name='parent image'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='image',
|
||||
name='source',
|
||||
field=models.PositiveSmallIntegerField(choices=[(0, 'Mobile'), (1, 'Web'), (2, 'All')], default=0, verbose_name='Source'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='image',
|
||||
name='title',
|
||||
field=models.CharField(default='', max_length=255, verbose_name='title'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='image',
|
||||
name='image',
|
||||
field=easy_thumbnails.fields.ThumbnailerImageField(upload_to=utils.methods.image_path, verbose_name='image file'),
|
||||
),
|
||||
]
|
||||
|
|
@ -9,6 +9,8 @@ class ImageSerializer(serializers.ModelSerializer):
|
|||
file = serializers.ImageField(source='image',
|
||||
write_only=True)
|
||||
title = serializers.CharField()
|
||||
orientation = serializers.ChoiceField(choices=models.Image.ORIENTATIONS,
|
||||
write_only=True)
|
||||
|
||||
# RESPONSE
|
||||
url = serializers.ImageField(source='image',
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ from . import views
|
|||
app_name = 'gallery'
|
||||
|
||||
urlpatterns = [
|
||||
path('upload/', views.ImageUploadView.as_view(), name='upload-image')
|
||||
path('upload/', views.ImageBaseView.as_view(), name='upload-image'),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -3,8 +3,17 @@ from rest_framework import generics
|
|||
from . import models, serializers
|
||||
|
||||
|
||||
class ImageUploadView(generics.CreateAPIView):
|
||||
"""Upload image to gallery"""
|
||||
class ImageBaseView(generics.CreateAPIView):
|
||||
"""Upload image to gallery."""
|
||||
model = models.Image
|
||||
queryset = models.Image.objects.all()
|
||||
serializer_class = serializers.ImageSerializer
|
||||
|
||||
|
||||
class NewsImageListView(ImageBaseView, generics.ListAPIView):
|
||||
"""Return list of uploaded images for news object."""
|
||||
|
||||
def get_queryset(self):
|
||||
"""Override get_queryset method."""
|
||||
qs = super(NewsImageListView, self).get_queryset()
|
||||
return qs.filter(news_gallery__news=self.kwargs.get('news_id'))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from news import models
|
||||
|
||||
|
||||
|
|
@ -12,3 +13,8 @@ class NewsTypeAdmin(admin.ModelAdmin):
|
|||
@admin.register(models.News)
|
||||
class NewsAdmin(admin.ModelAdmin):
|
||||
"""News admin."""
|
||||
|
||||
|
||||
@admin.register(models.NewsGallery)
|
||||
class NewsGalleryAdmin(admin.ModelAdmin):
|
||||
"""News gallery admin."""
|
||||
|
|
|
|||
21
apps/news/migrations/0014_auto_20190926_1156.py
Normal file
21
apps/news/migrations/0014_auto_20190926_1156.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Generated by Django 2.2.4 on 2019-09-26 11:56
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('news', '0013_auto_20190924_0806'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='news',
|
||||
name='image_url',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='news',
|
||||
name='preview_image_url',
|
||||
),
|
||||
]
|
||||
27
apps/news/migrations/0015_newsgallery.py
Normal file
27
apps/news/migrations/0015_newsgallery.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Generated by Django 2.2.4 on 2019-09-30 08:57
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gallery', '0002_auto_20190930_0714'),
|
||||
('news', '0014_auto_20190926_1156'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='NewsGallery',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('image', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='news_gallery', to='gallery.Image', verbose_name='gallery')),
|
||||
('news', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='news_gallery', to='news.News', verbose_name='news')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'news gallery',
|
||||
'verbose_name_plural': 'news galleries',
|
||||
},
|
||||
),
|
||||
]
|
||||
19
apps/news/migrations/0016_news_gallery.py
Normal file
19
apps/news/migrations/0016_news_gallery.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 2.2.4 on 2019-09-30 12:06
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gallery', '0002_auto_20190930_0714'),
|
||||
('news', '0015_newsgallery'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='news',
|
||||
name='gallery',
|
||||
field=models.ManyToManyField(through='news.NewsGallery', to='gallery.Image'),
|
||||
),
|
||||
]
|
||||
|
|
@ -83,6 +83,8 @@ class News(BaseAttributes, TranslatedFieldsMixin):
|
|||
verbose_name=_('country'))
|
||||
tags = generic.GenericRelation(to='main.MetaDataContent')
|
||||
|
||||
gallery = models.ManyToManyField('gallery.Image', through='news.NewsGallery')
|
||||
|
||||
objects = NewsQuerySet.as_manager()
|
||||
|
||||
class Meta:
|
||||
|
|
@ -103,7 +105,7 @@ class NewsGalleryQuerySet(models.QuerySet):
|
|||
"""QuerySet for model News"""
|
||||
|
||||
def originals(self):
|
||||
"""Return QuerySet with originals images."""
|
||||
"""Return QuerySet with original images."""
|
||||
return self.filter(gallery__parent__isnull=True)
|
||||
|
||||
def crops(self):
|
||||
|
|
@ -117,10 +119,10 @@ class NewsGallery(models.Model):
|
|||
related_name='news_gallery',
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name=_('news'))
|
||||
gallery = models.ForeignKey('gallery.Image', null=True,
|
||||
related_name='news_gallery',
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name=_('gallery'))
|
||||
image = models.ForeignKey('gallery.Image', null=True,
|
||||
related_name='news_gallery',
|
||||
on_delete=models.SET_NULL,
|
||||
verbose_name=_('gallery'))
|
||||
|
||||
objects = NewsGalleryQuerySet.as_manager()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
"""News app common serializers."""
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from gallery.models import Image
|
||||
from gallery.serializers import ImageSerializer
|
||||
from location import models as location_models
|
||||
from location.serializers import CountrySimpleSerializer
|
||||
from main.serializers import MetaDataContentSerializer
|
||||
|
|
@ -28,6 +31,7 @@ class NewsBaseSerializer(serializers.ModelSerializer):
|
|||
# related fields
|
||||
news_type = NewsTypeSerializer(read_only=True)
|
||||
tags = MetaDataContentSerializer(read_only=True, many=True)
|
||||
gallery = ImageSerializer(read_only=True, many=True)
|
||||
|
||||
slug = serializers.SlugField(allow_blank=False, required=True, max_length=50)
|
||||
|
||||
|
|
@ -43,6 +47,7 @@ class NewsBaseSerializer(serializers.ModelSerializer):
|
|||
'news_type',
|
||||
'tags',
|
||||
'slug',
|
||||
'gallery',
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -100,3 +105,43 @@ class NewsBackOfficeDetailSerializer(NewsBackOfficeBaseSerializer,
|
|||
'country_id',
|
||||
)
|
||||
|
||||
|
||||
class NewsBackOfficeGallerySerializer(serializers.ModelSerializer):
|
||||
"""Serializer class for model NewsGallery."""
|
||||
image = ImageSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
"""Meta class"""
|
||||
model = models.NewsGallery
|
||||
fields = [
|
||||
'id',
|
||||
'image',
|
||||
]
|
||||
|
||||
def get_request_kwargs(self):
|
||||
"""Get url kwargs from request."""
|
||||
return self.context.get('request').parser_context.get('kwargs')
|
||||
|
||||
def validate(self, attrs):
|
||||
"""Override validate method."""
|
||||
news_pk = self.get_request_kwargs().get('pk')
|
||||
image_id = self.get_request_kwargs().get('image_id')
|
||||
|
||||
news_qs = models.News.objects.filter(pk=news_pk)
|
||||
image_qs = Image.objects.filter(id=image_id)
|
||||
|
||||
if not news_qs.exists():
|
||||
raise serializers.ValidationError({'detail': _('News not found')})
|
||||
if not image_qs.exists():
|
||||
raise serializers.ValidationError({'detail': _('Image not found')})
|
||||
|
||||
news = news_qs.first()
|
||||
image = image_qs.first()
|
||||
|
||||
if news.news_gallery.filter(image=image).exists():
|
||||
raise serializers.ValidationError({'detail': _('Image is already added')})
|
||||
|
||||
attrs['news'] = news
|
||||
attrs['image'] = image
|
||||
|
||||
return attrs
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
"""News app urlpatterns for backoffice"""
|
||||
from django.urls import path
|
||||
|
||||
from news import views
|
||||
|
||||
app_name = 'news'
|
||||
|
|
@ -7,5 +8,9 @@ app_name = 'news'
|
|||
urlpatterns = [
|
||||
path('', views.NewsBackOfficeLCView.as_view(), name='list-create'),
|
||||
path('<int:pk>/', views.NewsBackOfficeRUDView.as_view(),
|
||||
name='retrieve-update-destroy'),
|
||||
name='gallery-retrieve-update-destroy'),
|
||||
path('<int:pk>/gallery/', views.NewsBackOfficeGalleryListView.as_view(),
|
||||
name='gallery-list'),
|
||||
path('<int:pk>/gallery/<int:image_id>/', views.NewsBackOfficeGalleryCreateDestroyView.as_view(),
|
||||
name='gallery-create-destroy'),
|
||||
]
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
"""News app views."""
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework import generics, permissions
|
||||
|
||||
from gallery.serializers import ImageSerializer
|
||||
from news import filters, models, serializers
|
||||
|
||||
|
||||
|
|
@ -59,6 +62,46 @@ class NewsBackOfficeLCView(NewsBackOfficeMixinView,
|
|||
return super().get_serializer_class()
|
||||
|
||||
|
||||
class NewsBackOfficeGalleryCreateDestroyView(NewsBackOfficeMixinView,
|
||||
generics.CreateAPIView,
|
||||
generics.DestroyAPIView):
|
||||
"""Resource for a create gallery for news for back-office users."""
|
||||
serializer_class = serializers.NewsBackOfficeGallerySerializer
|
||||
|
||||
def get_object(self):
|
||||
"""
|
||||
Returns the object the view is displaying.
|
||||
"""
|
||||
news_qs = self.filter_queryset(self.get_queryset())
|
||||
|
||||
news = get_object_or_404(news_qs, pk=self.kwargs['pk'])
|
||||
gallery = get_object_or_404(news.news_gallery, image_id=self.kwargs['image_id'])
|
||||
|
||||
# May raise a permission denied
|
||||
self.check_object_permissions(self.request, gallery)
|
||||
|
||||
return gallery
|
||||
|
||||
|
||||
class NewsBackOfficeGalleryListView(NewsBackOfficeMixinView, generics.ListAPIView):
|
||||
"""Resource for returning gallery for news for back-office users."""
|
||||
serializer_class = ImageSerializer
|
||||
|
||||
def get_object(self):
|
||||
"""Override get_object method."""
|
||||
qs = super(NewsBackOfficeGalleryListView, self).get_queryset()
|
||||
news = get_object_or_404(qs, pk=self.kwargs['pk'])
|
||||
|
||||
# May raise a permission denied
|
||||
self.check_object_permissions(self.request, news)
|
||||
|
||||
return news
|
||||
|
||||
def get_queryset(self):
|
||||
"""Override get_queryset method."""
|
||||
return self.get_object().gallery.all()
|
||||
|
||||
|
||||
class NewsBackOfficeRUDView(NewsBackOfficeMixinView,
|
||||
generics.RetrieveUpdateDestroyAPIView):
|
||||
"""Resource for detailed information about news for back-office users."""
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user