Oon*_*nah 5 python django rest json django-rest-framework
我正在使用Django Rest框架在Django中创建REST API,并且无法使用任何其他库或插件。过去几天我一直遇到问题,无法解决。
在我的seralizer.py中,我有以下内容
class BookSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source = 'owner.username')
genres = serializers.ChoiceField(choices=Genre.objects.values_list())
# genres = GenreSerializer()
class Meta:
model = VideoGame
fields = ('title', 'description', 'brief', 'genres', 'owner')
Run Code Online (Sandbox Code Playgroud)
我想这样,当用户访问GUI并尝试制作新书时,他们可以从选择字段中选择一种体裁,然后将其翻译成其ID。如果用户通过rest API访问,则他们还必须输入ID。
当数据库为空白时,我可以成功地将新书发布到服务器上,并使用choicefield选择下拉列表。但是,当数据库中有一个条目时,出现以下错误。当我用序列化程序替换choicefield时,这解决了。但是,然后剩下输入字段而不是选择字段。有谁知道我该怎么解决?
TypeError at /book/
<Genre: Genre object> is not JSON serializable
Run Code Online (Sandbox Code Playgroud)
您需要查看 a) 期望ChoiceField收到什么选择以及 b)values_list()返回什么。
a)从文档中期望“有效值列表或元组列表ChoiceField” 。 在这种情况下,有效值将是您的流派的主键 ID。(key, display_name)
b)根据没有参数的文档,返回 “模型中的所有字段,按照它们声明的顺序”。values_list()
我认为您不可能通过使用choices=Genre.objects.values_list()...得到问题中显示的错误消息...也许您尝试过choices=Genre.objects.all()?
无论如何,你可以这样做:
class BookSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source = 'owner.username')
genres = serializers.ChoiceField(choices=Genre.objects.values_list('pk', flat=True))
Run Code Online (Sandbox Code Playgroud)
如果您的模型上有一个字段Genre可以作为一个很好的“显示名称”,那么您可以这样做:
class BookSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source = 'owner.username')
genres = serializers.ChoiceField(choices=Genre.objects.values_list('pk', 'name'))
Run Code Online (Sandbox Code Playgroud)
然而,上述两个选项都存在一个问题,即一旦您导入包含资源的文件,查询集就会被评估。(因为它立即被 ChoiceField 转换为列表)。
在导入时产生此类副作用是不好的做法。此外,由于每次启动服务器时只会评估一次,因此当您更改流派时,选择将过时。
幸运的是,有一个更好的选择:
http://www.django-rest-framework.org/api-guide/relations/#primarykeylatedfield
这类似于 Django 中的 ModelChoiceField。它有一个queryset用于验证选择的参数...但与 ChoiceField 不同的是,它知道不要立即评估查询集。每次需要验证选择时都会对其进行评估。
所以你应该这样做:
class BookSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source = 'owner.username')
genres = serializers.PrimaryKeyRelatedField(queryset=Genre.objects.all())
Run Code Online (Sandbox Code Playgroud)
如果您需要为关系字段上的选择自定义“显示名称”,您可以在此处查看文档。
| 归档时间: |
|
| 查看次数: |
4597 次 |
| 最近记录: |