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 .models import Publication, Rating, Category
|
||||
from .models import Publication, Rating
|
||||
|
||||
# Register your models here.
|
||||
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_filter = ('content_type', 'is_pinned')
|
||||
readonly_fields = ('time_created', 'time_updated')
|
||||
@ -17,4 +17,3 @@ class RatingAdmin(admin.ModelAdmin):
|
||||
|
||||
admin.site.register(Publication, PublicationAdmin)
|
||||
admin.site.register(Rating, RatingAdmin)
|
||||
admin.site.register(Category)
|
||||
@ -1,6 +1,5 @@
|
||||
from typing import TypeVar
|
||||
from django.db.models import Avg
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.db import models
|
||||
|
||||
T = TypeVar('T')
|
||||
@ -8,7 +7,7 @@ T = TypeVar('T')
|
||||
class PublicationQuerySet(models.QuerySet[T]):
|
||||
def with_score(self):
|
||||
qs = self
|
||||
qs = qs.annotate(average_score=Coalesce(Avg("ratings__score"), 0.0))
|
||||
qs = qs.annotate(average_score=Avg("ratings__score"))
|
||||
return qs
|
||||
|
||||
def only_publish(self):
|
||||
|
||||
@ -48,6 +48,10 @@ class Publication(models.Model):
|
||||
def __str__(self):
|
||||
return f'Content #{self.pk}'
|
||||
|
||||
@property
|
||||
def average_score(self) -> int:
|
||||
return getattr(self, "average_score", None)
|
||||
|
||||
def clean(self):
|
||||
errors = []
|
||||
|
||||
|
||||
@ -12,31 +12,7 @@ class CategorySerializer(serializers.ModelSerializer):
|
||||
class PublicationSerializer(serializers.ModelSerializer):
|
||||
category_detail = CategorySerializer(source="category", read_only=True)
|
||||
user_detail = PublicUserSerializer(source="user", read_only=True)
|
||||
average_score = serializers.SerializerMethodField(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
|
||||
average_score = serializers.IntegerField(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Publication
|
||||
|
||||
@ -40,9 +40,6 @@ class PublicationsAPIView(ListCreateAPIView):
|
||||
|
||||
return super().get_permissions()
|
||||
|
||||
def perform_create(self, serializer: PublicationSerializer):
|
||||
serializer.save(user=self.request.user)
|
||||
|
||||
@extend_schema(
|
||||
tags=['Publications'],
|
||||
summary='Publication details',
|
||||
@ -70,9 +67,6 @@ class AdminPublicationsAPIView(PublicationsAPIView):
|
||||
def get_permissions(self):
|
||||
return [IsProfessorOnly()]
|
||||
|
||||
def perform_create(self, serializer: AdminPublicationSerializer):
|
||||
serializer.save(user=self.request.user)
|
||||
|
||||
@extend_schema(
|
||||
tags=['Publications'],
|
||||
summary='CRUD for publication (only admin or professor)',
|
||||
@ -98,11 +92,10 @@ class CategoryListAPIView(ListCreateAPIView):
|
||||
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
|
||||
ordering = ['name']
|
||||
search_fields = ['name']
|
||||
pagination_class = None
|
||||
|
||||
def get_permissions(self):
|
||||
if self.request.method == 'POST':
|
||||
return [IsAdminUser()]
|
||||
return [IsAdminUser]
|
||||
return super().get_permissions()
|
||||
|
||||
@extend_schema(
|
||||
|
||||
@ -12,14 +12,11 @@ django-rest-framework==0.1.0
|
||||
djangorestframework==3.16.1
|
||||
djangorestframework_simplejwt==5.5.1
|
||||
drf-spectacular==0.29.0
|
||||
gunicorn==23.0.0
|
||||
idna==3.11
|
||||
inflection==0.5.1
|
||||
jsonschema==4.25.1
|
||||
jsonschema-specifications==2025.9.1
|
||||
oauthlib==3.3.1
|
||||
packaging==25.0
|
||||
pillow==12.0.0
|
||||
pycparser==2.23
|
||||
PyJWT==2.10.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 import status
|
||||
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.authtoken.models import Token
|
||||
|
||||
@ -87,17 +87,9 @@ class UserAPIView(RetrieveUpdateDestroyAPIView):
|
||||
serializer_class = UserForAdminSerializer
|
||||
permission_classes = [IsAdminUser]
|
||||
|
||||
@extend_schema(
|
||||
tags=['Users'],
|
||||
methods=['GET'],
|
||||
summary='List school ids',
|
||||
)
|
||||
@extend_schema(
|
||||
tags=['Users'],
|
||||
methods=['POST'],
|
||||
summary='Create new school id (only admin)',
|
||||
)
|
||||
class SchoolListAPIView(ListCreateAPIView):
|
||||
@extend_schema(tags=['Users'],
|
||||
summary='List of all available school ids (only admin)')
|
||||
class SchoolListAPIView(ListAPIView):
|
||||
queryset = SchoolID.objects.all()
|
||||
serializer_class = SchoolIDSerializer
|
||||
permission_classes = [IsAdminUser]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user