Spaces:
Sleeping
Sleeping
| from drf_spectacular.utils import extend_schema_field | |
| from rest_framework import serializers | |
| from apps.skills.serializers import SkillSerializer | |
| from .models import Resource, ResourceCheckpoint, SkillResource | |
| class ResourceCheckpointSerializer(serializers.ModelSerializer): | |
| # Populated when the serializer context carries a `completed_checkpoint_ids` | |
| # set β e.g. ResourceDetailView preloads the current user's completed | |
| # checkpoint IDs for the fetched resource. Absent in contexts without a | |
| # user (schema generation, seed scripts) β falls back to False. | |
| is_completed = serializers.SerializerMethodField() | |
| class Meta: | |
| model = ResourceCheckpoint | |
| fields = ['id', 'order_index', 'title', 'url_fragment', | |
| 'estimated_minutes', 'source', 'is_completed'] | |
| def get_is_completed(self, obj) -> bool: | |
| completed = self.context.get('completed_checkpoint_ids') or set() | |
| return obj.id in completed | |
| class SkillResourceSerializer(serializers.ModelSerializer): | |
| skill = SkillSerializer(read_only=True) | |
| class Meta: | |
| model = SkillResource | |
| fields = ['skill', 'relevance_score'] | |
| class ResourceListSerializer(serializers.ModelSerializer): | |
| # Populated by an Exists() annotation on the view's queryset β see | |
| # ResourceListView. Keep as BooleanField so it fails loud if the view | |
| # ever forgets the annotation. | |
| has_checkpoints = serializers.BooleanField(read_only=True) | |
| class Meta: | |
| model = Resource | |
| fields = ['id', 'title', 'provider', 'url', 'difficulty_level', | |
| 'duration', 'type', 'rating', 'has_checkpoints'] | |
| class ResourceDetailSerializer(serializers.ModelSerializer): | |
| checkpoints = ResourceCheckpointSerializer(many=True, read_only=True) | |
| skill_mappings = serializers.SerializerMethodField() | |
| class Meta: | |
| model = Resource | |
| fields = ['id', 'title', 'provider', 'url', 'difficulty_level', | |
| 'duration', 'type', 'rating', 'checkpoints', 'skill_mappings'] | |
| def get_skill_mappings(self, obj): | |
| return SkillResourceSerializer( | |
| SkillResource.objects.filter(resource=obj).select_related('skill'), | |
| many=True, | |
| ).data | |
| class ResourceAdminSerializer(serializers.ModelSerializer): | |
| """Full-field writable Resource serializer for admin CRUD. | |
| Linked skills and checkpoints are managed via separate endpoints | |
| (SkillResourceAdminViewSet, ResourceCheckpointAdminViewSet) so that each | |
| concern has its own CRUD surface β matches the existing Django admin UX. | |
| """ | |
| class Meta: | |
| model = Resource | |
| fields = ['id', 'title', 'provider', 'url', 'difficulty_level', | |
| 'duration', 'type', 'rating', 'created_at'] | |
| read_only_fields = ['created_at'] | |
| class ResourceCheckpointAdminSerializer(serializers.ModelSerializer): | |
| class Meta: | |
| model = ResourceCheckpoint | |
| fields = ['id', 'resource', 'order_index', 'title', 'url_fragment', | |
| 'estimated_minutes', 'source', 'extracted_at'] | |
| class SkillResourceAdminSerializer(serializers.ModelSerializer): | |
| skill_detail = SkillSerializer(source='skill', read_only=True) | |
| class Meta: | |
| model = SkillResource | |
| fields = ['id', 'skill', 'skill_detail', 'resource', 'relevance_score'] | |