0

Here I have an endpoint to create media content for users. The endpoint works, but I have a feeling my design implementation is incorrect.

Should validation logic be contained in serializers create? Is this bad practice? I attempted to move validation logic to models.py, but ran into issues with accessing the model, specifically this line - self.model(user=user, category=category).

view.py

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from .models import UserMedia
from .renderers import UserMediaSerializerJSONRenderer
from .serializers import UserMediaSerializer


class UserMediaCreateAPIView(APIView):
    permission_classes = (IsAuthenticated,)
    renderer_classes = (UserMediaSerializerJSONRenderer,)
    serializer_class = UserMediaSerializer

    def post(self, request):
        userMedia = request.data.get('userMedia', {})
        serializer = self.serializer_class(data=userMedia)
        serializer.is_valid(raise_exception=True)
        serializer.save(user=request.user, category=userMedia['category'])

        return Response(serializer.data, status=status.HTTP_201_CREATED)

serializers.py

from rest_framework import serializers

from .models import UserMedia


class UserMediaSerializer(serializers.ModelSerializer):
    category = serializers.CharField(allow_blank=False, required=True)

    class Meta:
        model = UserMedia
        fields = ('category',)
        read_only_fields = ('category',)

    def get_category(self, obj):
        if obj.category:
            return obj.category

        return 'N/A'

    def create(self, validated_data):
        if validated_data['user'] is None:
            raise TypeError('User media must have a user')

        if validated_data['category'] is None:
            raise TypeError('User media must have a category.')

        if validated_data['category'] not in dict(UserMedia.CATEGORY_CHOICES):
            raise TypeError('User media category is not available.')

        userMedia = UserMedia(**validated_data)
        userMedia.save()
        return userMedia

models.py

from django.db import models

class UserMedia(models.Model):
    user = models.ForeignKey('authentication.User', on_delete=models.CASCADE, related_name='media')

    MUSIC = 'M'
    VIDEO = 'V'
    CATEGORY_CHOICES = (
        (MUSIC, 'Music'),
        (VIDEO, 'Video'),
    )
    category = models.CharField(max_length=1, choices=CATEGORY_CHOICES, blank=False)

1 Answer 1

1

The validation should be done in your view. The serializers should just be for serializing data. The validation should be done in your view then the serializer is called from your view. As far as this line self.model(user=user, category=category) is concerned it does not appear that you ever import user any where.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.