A thread belongs to a board. So I would like the ThreadList view to accept a POST request with the foreign key board
. What I have attempted results in an error. AssertionError: Relational field must provide a queryset argument, override get_queryset, or set read_only=True
serializers.py
class ThreadSerializer(serializers.ModelSerializer):
post = PostSerializer(many=True, read_only=True)
# board = serializers.ReadOnlyField(source='board.id')
board = serializers.PrimaryKeyRelatedField(source='board.id')
class Meta:
model = Thread
fields = ['id', 'title', 'post', 'board']
views.py
class ThreadList(generics.ListCreateAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def perform_create(self, serializer):
serializer.save(thread_admin=self.request.user)
queryset = Thread.objects.all()
serializer_class = ThreadSerializer
models.py
class Board(models.Model):
name = models.CharField(max_length=25, unique=True)
created = models.DateTimeField(auto_now_add=True)
board_admin = models.ForeignKey('auth.User', on_delete=models.CASCADE, related_name='board_admin')
board_moderator = models.ManyToManyField(User, related_name='board_moderator')
class Meta:
ordering = ['created']
class Thread(models.Model):
title = models.CharField(max_length=250)
created = models.DateTimeField(auto_now_add=True)
thread_admin = models.ForeignKey('auth.User', on_delete=models.CASCADE, related_name='thread')
board = models.ForeignKey(Board, on_delete=models.CASCADE, related_name="thread")
class Meta:
ordering = ['created']
CodePudding user response:
serializers.PrimaryKeyRelatedField
has a required argument queryset
that needs to include to tell what id of which queryset
needs to be validated against.
In your case, it should be
class ThreadSerializer(serializers.ModelSerializer):
...
board = serializers.PrimaryKeyRelatedField(queryset=Board.objects.all())
...
Notes
Notice that you don't need to specify source='board.id'
since django-rest-framework
already handles that for you.
Extra
If there's no extra parameters that will be pass into serializers.PrimaryKeyRelatedField
to change the default behavior, you can just include board
in class Meta
's fields
and no need to use serializers.PrimaryKeyRelatedField
manually.
class ThreadSerializer(serializers.ModelSerializer):
post = PostSerializer(many=True, read_only=True)
class Meta:
model = Thread
fields = ['id', 'title', 'post', 'board']