Django Rest Framework 允许请求在 CreateAPIView 中设置外键字段
Django Rest Framework Allow a request to set a foreign key Field in CreateAPIView
一个线程属于一个板。所以我希望 ThreadList 视图接受带有外键 board
的 POST 请求。我的尝试导致错误。 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
,需要包含该参数以告知需要验证哪个 ID queryset
。
你的情况应该是
class ThreadSerializer(serializers.ModelSerializer):
...
board = serializers.PrimaryKeyRelatedField(queryset=Board.objects.all())
...
备注
请注意,您不需要指定 source='board.id'
,因为 django-rest-framework
已经为您处理了。
额外
如果没有额外的参数将传递给 serializers.PrimaryKeyRelatedField
以更改默认行为,您可以只在 class Meta
的 fields
中包含 board
而没有需要手动使用 serializers.PrimaryKeyRelatedField
。
class ThreadSerializer(serializers.ModelSerializer):
post = PostSerializer(many=True, read_only=True)
class Meta:
model = Thread
fields = ['id', 'title', 'post', 'board']
一个线程属于一个板。所以我希望 ThreadList 视图接受带有外键 board
的 POST 请求。我的尝试导致错误。 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
,需要包含该参数以告知需要验证哪个 ID queryset
。
你的情况应该是
class ThreadSerializer(serializers.ModelSerializer):
...
board = serializers.PrimaryKeyRelatedField(queryset=Board.objects.all())
...
备注
请注意,您不需要指定 source='board.id'
,因为 django-rest-framework
已经为您处理了。
额外
如果没有额外的参数将传递给 serializers.PrimaryKeyRelatedField
以更改默认行为,您可以只在 class Meta
的 fields
中包含 board
而没有需要手动使用 serializers.PrimaryKeyRelatedField
。
class ThreadSerializer(serializers.ModelSerializer):
post = PostSerializer(many=True, read_only=True)
class Meta:
model = Thread
fields = ['id', 'title', 'post', 'board']