Compare commits
No commits in common. "2a11a30cd55c7b16d0c79e7e1a8e8e1458540d71" and "ed84b97f583f61ca88716d658eb695f1c3a2f726" have entirely different histories.
2a11a30cd5
...
ed84b97f58
@ -1,9 +1,9 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from .models import Publication, Rating, Category
|
from .models import Publication, Rating
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
class PublicationAdmin(admin.ModelAdmin):
|
class PublicationAdmin(admin.ModelAdmin):
|
||||||
list_display = ('pk', 'content_type', 'category', 'is_pinned', 'user', 'time_created', 'time_updated')
|
list_display = ('pk', 'content_type', 'is_pinned', 'user', 'time_created', 'time_updated')
|
||||||
list_display_links = ('pk', 'content_type')
|
list_display_links = ('pk', 'content_type')
|
||||||
list_filter = ('content_type', 'is_pinned')
|
list_filter = ('content_type', 'is_pinned')
|
||||||
readonly_fields = ('time_created', 'time_updated')
|
readonly_fields = ('time_created', 'time_updated')
|
||||||
@ -17,4 +17,3 @@ class RatingAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
admin.site.register(Publication, PublicationAdmin)
|
admin.site.register(Publication, PublicationAdmin)
|
||||||
admin.site.register(Rating, RatingAdmin)
|
admin.site.register(Rating, RatingAdmin)
|
||||||
admin.site.register(Category)
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
from django.db.models import Avg
|
from django.db.models import Avg
|
||||||
from django.db.models.functions import Coalesce
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
T = TypeVar('T')
|
T = TypeVar('T')
|
||||||
@ -8,7 +7,7 @@ T = TypeVar('T')
|
|||||||
class PublicationQuerySet(models.QuerySet[T]):
|
class PublicationQuerySet(models.QuerySet[T]):
|
||||||
def with_score(self):
|
def with_score(self):
|
||||||
qs = self
|
qs = self
|
||||||
qs = qs.annotate(average_score=Coalesce(Avg("ratings__score"), 0.0))
|
qs = qs.annotate(average_score=Avg("ratings__score"))
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def only_publish(self):
|
def only_publish(self):
|
||||||
|
|||||||
@ -48,6 +48,10 @@ class Publication(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'Content #{self.pk}'
|
return f'Content #{self.pk}'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def average_score(self) -> int:
|
||||||
|
return getattr(self, "average_score", None)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
|
|||||||
@ -12,31 +12,7 @@ class CategorySerializer(serializers.ModelSerializer):
|
|||||||
class PublicationSerializer(serializers.ModelSerializer):
|
class PublicationSerializer(serializers.ModelSerializer):
|
||||||
category_detail = CategorySerializer(source="category", read_only=True)
|
category_detail = CategorySerializer(source="category", read_only=True)
|
||||||
user_detail = PublicUserSerializer(source="user", read_only=True)
|
user_detail = PublicUserSerializer(source="user", read_only=True)
|
||||||
average_score = serializers.SerializerMethodField(read_only=True)
|
average_score = serializers.IntegerField(read_only=True)
|
||||||
|
|
||||||
def get_average_score(self, obj):
|
|
||||||
return getattr(obj, 'average_score', 0)
|
|
||||||
|
|
||||||
def validate(self, attrs):
|
|
||||||
content_type = attrs.get('content_type')
|
|
||||||
image = attrs.get('image')
|
|
||||||
video = attrs.get('video')
|
|
||||||
|
|
||||||
errors = {}
|
|
||||||
|
|
||||||
if content_type == 'image' and not image:
|
|
||||||
errors['image'] = 'Required image file'
|
|
||||||
|
|
||||||
if content_type == 'video' and not video:
|
|
||||||
errors['video'] = 'Required video file'
|
|
||||||
|
|
||||||
if image and video:
|
|
||||||
errors['non_field_errors'] = 'You must upload either a video or an image, not both'
|
|
||||||
|
|
||||||
if errors:
|
|
||||||
raise serializers.ValidationError(errors)
|
|
||||||
|
|
||||||
return attrs
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Publication
|
model = Publication
|
||||||
|
|||||||
@ -40,9 +40,6 @@ class PublicationsAPIView(ListCreateAPIView):
|
|||||||
|
|
||||||
return super().get_permissions()
|
return super().get_permissions()
|
||||||
|
|
||||||
def perform_create(self, serializer: PublicationSerializer):
|
|
||||||
serializer.save(user=self.request.user)
|
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
tags=['Publications'],
|
tags=['Publications'],
|
||||||
summary='Publication details',
|
summary='Publication details',
|
||||||
@ -70,9 +67,6 @@ class AdminPublicationsAPIView(PublicationsAPIView):
|
|||||||
def get_permissions(self):
|
def get_permissions(self):
|
||||||
return [IsProfessorOnly()]
|
return [IsProfessorOnly()]
|
||||||
|
|
||||||
def perform_create(self, serializer: AdminPublicationSerializer):
|
|
||||||
serializer.save(user=self.request.user)
|
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
tags=['Publications'],
|
tags=['Publications'],
|
||||||
summary='CRUD for publication (only admin or professor)',
|
summary='CRUD for publication (only admin or professor)',
|
||||||
@ -98,11 +92,10 @@ class CategoryListAPIView(ListCreateAPIView):
|
|||||||
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
|
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
|
||||||
ordering = ['name']
|
ordering = ['name']
|
||||||
search_fields = ['name']
|
search_fields = ['name']
|
||||||
pagination_class = None
|
|
||||||
|
|
||||||
def get_permissions(self):
|
def get_permissions(self):
|
||||||
if self.request.method == 'POST':
|
if self.request.method == 'POST':
|
||||||
return [IsAdminUser()]
|
return [IsAdminUser]
|
||||||
return super().get_permissions()
|
return super().get_permissions()
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
|
|||||||
@ -12,14 +12,11 @@ django-rest-framework==0.1.0
|
|||||||
djangorestframework==3.16.1
|
djangorestframework==3.16.1
|
||||||
djangorestframework_simplejwt==5.5.1
|
djangorestframework_simplejwt==5.5.1
|
||||||
drf-spectacular==0.29.0
|
drf-spectacular==0.29.0
|
||||||
gunicorn==23.0.0
|
|
||||||
idna==3.11
|
idna==3.11
|
||||||
inflection==0.5.1
|
inflection==0.5.1
|
||||||
jsonschema==4.25.1
|
jsonschema==4.25.1
|
||||||
jsonschema-specifications==2025.9.1
|
jsonschema-specifications==2025.9.1
|
||||||
oauthlib==3.3.1
|
oauthlib==3.3.1
|
||||||
packaging==25.0
|
|
||||||
pillow==12.0.0
|
|
||||||
pycparser==2.23
|
pycparser==2.23
|
||||||
PyJWT==2.10.1
|
PyJWT==2.10.1
|
||||||
python-dotenv==1.2.1
|
python-dotenv==1.2.1
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from rest_framework.request import Request
|
|||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.generics import RetrieveUpdateDestroyAPIView, ListAPIView, RetrieveAPIView, ListCreateAPIView
|
from rest_framework.generics import RetrieveUpdateDestroyAPIView, ListAPIView, RetrieveAPIView
|
||||||
from rest_framework.permissions import IsAuthenticated, IsAdminUser
|
from rest_framework.permissions import IsAuthenticated, IsAdminUser
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
|
|
||||||
@ -87,17 +87,9 @@ class UserAPIView(RetrieveUpdateDestroyAPIView):
|
|||||||
serializer_class = UserForAdminSerializer
|
serializer_class = UserForAdminSerializer
|
||||||
permission_classes = [IsAdminUser]
|
permission_classes = [IsAdminUser]
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(tags=['Users'],
|
||||||
tags=['Users'],
|
summary='List of all available school ids (only admin)')
|
||||||
methods=['GET'],
|
class SchoolListAPIView(ListAPIView):
|
||||||
summary='List school ids',
|
|
||||||
)
|
|
||||||
@extend_schema(
|
|
||||||
tags=['Users'],
|
|
||||||
methods=['POST'],
|
|
||||||
summary='Create new school id (only admin)',
|
|
||||||
)
|
|
||||||
class SchoolListAPIView(ListCreateAPIView):
|
|
||||||
queryset = SchoolID.objects.all()
|
queryset = SchoolID.objects.all()
|
||||||
serializer_class = SchoolIDSerializer
|
serializer_class = SchoolIDSerializer
|
||||||
permission_classes = [IsAdminUser]
|
permission_classes = [IsAdminUser]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user