Django Rest Framework Разрешить запрос на установку поля внешнего ключа в CreateAPIView

Тема принадлежит форуму. Поэтому я хочу, чтобы представление ThreadList принимало POST-запрос с внешним ключом board. То, что я попытался сделать, приводит к ошибке. 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']

serializers.PrimaryKeyRelatedField имеет обязательный аргумент queryset, который нужно включить, чтобы указать, по какому идентификатору queryset нужно проводить проверку.

В вашем случае это должно быть

class ThreadSerializer(serializers.ModelSerializer):
    ...
    board = serializers.PrimaryKeyRelatedField(queryset=Board.objects.all())
    ...

Примечания

Обратите внимание, что вам не нужно указывать source='board.id', так как django-rest-framework уже обрабатывает это за вас.

Extra

Если нет дополнительных параметров, которые будут передаваться в serializers.PrimaryKeyRelatedField для изменения поведения по умолчанию, вы можете просто включить board в class Meta в fields и нет необходимости использовать serializers.PrimaryKeyRelatedField вручную.

class ThreadSerializer(serializers.ModelSerializer):
    post = PostSerializer(many=True, read_only=True)

    class Meta:
        model = Thread
        fields = ['id', 'title', 'post', 'board']
Вернуться на верх