Reputation: 313
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)
Upvotes: 0
Views: 54
Reputation: 1253
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.
Upvotes: 1