Reputation: 452
I have a model Classroom
which has a field code
that is generated automatically
from django.utils.crypto import get_random_string
class Classroom(models.Model):
CODE_LEN = 16
teacher = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
name = models.CharField(max_length=250)
subject = models.CharField(max_length=50)
code = models.CharField(max_length=CODE_LEN, unique=True)
def save(self, *args, **kwargs):
while True:
self.code = get_random_string(length=16)
if not Classroom.objects.filter(code=self.code).exists():
break
super().save(*args, **kwargs)
The serializer for Classroom
is -
class ClassroomSerializer(serializers.ModelSerializer):
class Meta:
model = Classroom
fields = ('teacher', 'name', 'subject', 'code')
This is the view for creating new Classroom
-
class ListCreateClassroom(APIView):
def get(self, request):
classrooms = Classroom.objects.all()
serializer = ClassroomSerializer(classrooms, many=True)
return Response(serializer.data)
def post(self, request):
token = request.headers.get('Authorization').split()[1]
token_obj = AccessToken.objects.get(token=token)
teacher = token_obj.user.pk
request.data.update({"teacher": teacher})
serializer = ClassroomSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
When I send an api request to add new classroom, the request doesn't contain the code
field because of which serializer.is_valid()
throws error.
One way to solve it would be to create a code
in the view and add it to the request
.
But, is there a better way?
Upvotes: 0
Views: 208
Reputation: 2827
Simply set the code
field in the serializer to read_only=True
:
class ClassroomSerializer(serializers.ModelSerializer):
code = serializers.CharField(read_only=True)
class Meta:
model = Classroom
fields = ('teacher', 'name', 'subject', 'code')
Upvotes: 1