diff --git a/api/v1/serializers.py b/api/v1/serializers.py index 4b26877e..96630f50 100644 --- a/api/v1/serializers.py +++ b/api/v1/serializers.py @@ -74,7 +74,7 @@ class GalleryImageSerializer(GalleryImageCreateSerializer): img = ImageObjectSerializer() -class MaterialSerializer(serializers.ModelSerializer): +class MaterialCreateSerializer(serializers.ModelSerializer): class Meta: model = Material @@ -89,12 +89,15 @@ class MaterialSerializer(serializers.ModelSerializer): read_only_fields = ( 'id', - 'cover', 'created_at', 'update_at', ) +class MaterialSerializer(MaterialCreateSerializer): + cover = ImageObjectSerializer() + + class LikeSerializer(serializers.ModelSerializer): class Meta: @@ -127,9 +130,7 @@ class CategorySerializer(serializers.ModelSerializer): ) -class CourseSerializer(serializers.ModelSerializer): - cover = ImageObjectSerializer() - gallery = GallerySerializer() +class CourseCreateSerializer(serializers.ModelSerializer): class Meta: model = Course @@ -164,15 +165,14 @@ class CourseSerializer(serializers.ModelSerializer): ) -class CourseRetrieveSerializer(CourseSerializer): +class CourseSerializer(CourseCreateSerializer): category = CategorySerializer() materials = MaterialSerializer(many=True) cover = ImageObjectSerializer() gallery = GallerySerializer() -class LessonSerializer(serializers.ModelSerializer): - cover = ImageObjectSerializer() +class LessonCreateSerializer(serializers.ModelSerializer): class Meta: model = Lesson @@ -189,15 +189,18 @@ class LessonSerializer(serializers.ModelSerializer): read_only_fields = ( 'id', - 'cover', 'content', 'created_at', 'update_at', ) -class ImageSerializer(serializers.ModelSerializer): - img = ImageObjectSerializer() +class LessonSerializer(LessonCreateSerializer): + course = CourseSerializer() + cover = ImageObjectSerializer() + + +class ImageCreateSerializer(serializers.ModelSerializer): class Meta: model = Image @@ -219,7 +222,13 @@ class ImageSerializer(serializers.ModelSerializer): ) -class TextSerializer(serializers.ModelSerializer): +class ImageSerializer(ImageCreateSerializer): + course = CourseSerializer() + lesson = LessonSerializer() + img = ImageObjectSerializer() + + +class TextCreateSerializer(serializers.ModelSerializer): class Meta: model = Text @@ -240,8 +249,12 @@ class TextSerializer(serializers.ModelSerializer): ) -class ImageTextSerializer(serializers.ModelSerializer): - img = ImageObjectSerializer() +class TextSerializer(TextCreateSerializer): + course = CourseSerializer() + lesson = LessonSerializer() + + +class ImageTextCreateSerializer(serializers.ModelSerializer): class Meta: model = ImageText @@ -264,7 +277,13 @@ class ImageTextSerializer(serializers.ModelSerializer): ) -class VideoSerializer(serializers.ModelSerializer): +class ImageTextSerializer(ImageTextCreateSerializer): + course = CourseSerializer() + lesson = LessonSerializer() + img = ImageObjectSerializer() + + +class VideoCreateSerializer(serializers.ModelSerializer): class Meta: model = Video @@ -285,6 +304,11 @@ class VideoSerializer(serializers.ModelSerializer): ) +class VideoSerializer(VideoCreateSerializer): + course = CourseSerializer() + lesson = LessonSerializer() + + class UserSerializer(serializers.ModelSerializer): class Meta: diff --git a/api/v1/views.py b/api/v1/views.py index af0b0e4a..db87e030 100644 --- a/api/v1/views.py +++ b/api/v1/views.py @@ -7,13 +7,17 @@ from rest_framework.response import Response from . import ExtendedModelViewSet from .serializers import ( - CategorySerializer, CourseSerializer, - MaterialSerializer, LikeSerializer, - ImageSerializer, TextSerializer, - ImageTextSerializer, VideoSerializer, - GallerySerializer, GalleryImageSerializer, GalleryImageCreateSerializer, + CategorySerializer, LikeSerializer, + CourseSerializer, CourseCreateSerializer, + MaterialSerializer, MaterialCreateSerializer, + ImageSerializer, ImageCreateSerializer, + TextSerializer, TextCreateSerializer, + ImageTextSerializer, ImageTextCreateSerializer, + VideoSerializer, VideoCreateSerializer, + GallerySerializer, + GalleryImageSerializer, GalleryImageCreateSerializer, UserSerializer, UserPhotoSerializer, - LessonSerializer, CourseRetrieveSerializer, + LessonSerializer, LessonCreateSerializer, ImageObjectSerializer, ) from .permissions import IsAdmin, IsAdminOrIsSelf, IsAuthorOrAdmin, IsAuthorObjectOrAdmin @@ -35,7 +39,11 @@ class ImageObjectViewSet(ExtendedModelViewSet): class MaterialViewSet(ExtendedModelViewSet): queryset = Material.objects.all() - serializer_class = MaterialSerializer + serializer_class = MaterialCreateSerializer + serializer_class_map = { + 'list': MaterialSerializer, + 'retrieve': MaterialSerializer, + } search_fields = ('title', 'short_description',) ordering_fields = ('title', 'created_at', 'update_at',) # permission_classes = (IsAdmin,) @@ -63,10 +71,10 @@ class CourseViewSet(ExtendedModelViewSet): ).prefetch_related( 'likes', 'materials', 'content', ).all() - serializer_class = CourseSerializer + serializer_class = CourseCreateSerializer serializer_class_map = { - 'list': CourseRetrieveSerializer, - 'retrieve': CourseRetrieveSerializer, + 'list': CourseSerializer, + 'retrieve': CourseSerializer, } filter_fields = ('category', 'status', 'is_infinite', 'is_featured',) search_fields = ('author__email', 'title', 'category__title',) @@ -82,7 +90,11 @@ class LessonViewSet(ExtendedModelViewSet): queryset = Lesson.objects.select_related( 'course', 'cover' ).prefetch_related('content').all() - serializer_class = LessonSerializer + serializer_class = LessonCreateSerializer + serializer_class_map = { + 'list': LessonSerializer, + 'retrieve': LessonSerializer, + } filter_fields = ('course',) search_fields = ('title', 'short_description',) ordering_fields = ('title', 'created_at', 'update_at',) @@ -97,7 +109,11 @@ class ImageViewSet(ExtendedModelViewSet): queryset = Image.objects.select_related( 'course', 'lesson', 'img', ).all() - serializer_class = ImageSerializer + serializer_class = ImageCreateSerializer + serializer_class_map = { + 'list': ImageSerializer, + 'retrieve': ImageSerializer, + } search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at', 'position',) # permission_classes = (IsAuthorOrAdmin,) @@ -110,7 +126,11 @@ class TextViewSet(ExtendedModelViewSet): queryset = Text.objects.select_related( 'course', 'lesson' ).all() - serializer_class = TextSerializer + serializer_class = TextCreateSerializer + serializer_class_map = { + 'list': TextSerializer, + 'retrieve': TextSerializer, + } search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at', 'position',) # permission_classes = (IsAuthorOrAdmin,) @@ -123,7 +143,11 @@ class ImageTextViewSet(ExtendedModelViewSet): queryset = ImageText.objects.select_related( 'course', 'lesson', 'img' ).all() - serializer_class = ImageTextSerializer + serializer_class = ImageTextCreateSerializer + serializer_class_map = { + 'list': ImageTextSerializer, + 'retrieve': ImageTextSerializer, + } search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at', 'position',) # permission_classes = (IsAuthorOrAdmin,) @@ -136,7 +160,11 @@ class VideoViewSet(ExtendedModelViewSet): queryset = Video.objects.select_related( 'course', 'lesson' ).all() - serializer_class = VideoSerializer + serializer_class = VideoCreateSerializer + serializer_class_map = { + 'list': VideoSerializer, + 'retrieve': VideoSerializer, + } search_fields = ('title',) ordering_fields = ('title', 'created_at', 'update_at', 'position',) # permission_classes = (IsAuthorOrAdmin,) diff --git a/apps/course/migrations/0026_auto_20180208_1053.py b/apps/course/migrations/0026_auto_20180208_1053.py new file mode 100644 index 00000000..60bac8b8 --- /dev/null +++ b/apps/course/migrations/0026_auto_20180208_1053.py @@ -0,0 +1,24 @@ +# Generated by Django 2.0.2 on 2018-02-08 10:53 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('course', '0025_course_gallery'), + ] + + operations = [ + migrations.AlterField( + model_name='course', + name='price', + field=models.DecimalField(blank=True, decimal_places=2, help_text='Если цена не выставлена, то курс бесплатный', max_digits=10, null=True, verbose_name='Цена курса'), + ), + migrations.AlterField( + model_name='material', + name='cover', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='material_covers', to='content.ImageObject', verbose_name='Обложка материала'), + ), + ] diff --git a/apps/course/models.py b/apps/course/models.py index a00250fe..61cca877 100644 --- a/apps/course/models.py +++ b/apps/course/models.py @@ -128,7 +128,11 @@ class Lesson(models.Model): class Material(models.Model): title = models.CharField('Название материала', max_length=100) - cover = models.ImageField('Фон материала', upload_to='materials') + cover = models.ForeignKey( + ImageObject, related_name='material_covers', + verbose_name='Обложка материала', on_delete=models.CASCADE, + null=True, blank=True, + ) short_description = models.TextField('Краткое описание материала') created_at = models.DateTimeField(auto_now_add=True) diff --git a/apps/user/models.py b/apps/user/models.py index 141073ce..5986e33c 100644 --- a/apps/user/models.py +++ b/apps/user/models.py @@ -41,3 +41,6 @@ class User(AbstractUser): USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username'] + + class Meta(AbstractUser.Meta): + ordering = ('-date_joined',) diff --git a/docker-compose.yml b/docker-compose.yml index f42e5b6b..a6d65c69 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,7 +28,7 @@ services: - DATABASE_SERVICE_HOST=db - REDIS_SERVICE_HOST=redis ports: - - "8000:8000" + - "${PORT}:8000" depends_on: - db - redis