Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用ChoiceField时,类型错误对象不可JSON序列化_Python_Json_Django_Rest_Django Rest Framework - Fatal编程技术网

Python 使用ChoiceField时,类型错误对象不可JSON序列化

Python 使用ChoiceField时,类型错误对象不可JSON序列化,python,json,django,rest,django-rest-framework,Python,Json,Django,Rest,Django Rest Framework,我正在使用Django REST框架在Django中创建REST API,不能使用任何其他库或插件。在过去的几天里,我遇到了一个问题,我很难解决 在我的seralizer.py中,我有以下内容 class BookSerializer(serializers.HyperlinkedModelSerializer): owner = serializers.ReadOnlyField(source = 'owner.username') genres = serializers.C

我正在使用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') 
我希望这样,当用户访问GUI并尝试制作新书时,他们可以从choicefield中选择流派,然后将其转换为ID。如果用户通过rest API访问,他们还必须输入ID

当数据库为空时,我能够成功地将新书发布到服务器,并使用choicefield选择下拉列表。但是当数据库有一个条目时,我得到下面的错误。当我用序列化程序替换choicefield时,这个问题就解决了。然而,我只剩下一个输入字段,而不是选择字段。有人知道我怎么解决这个问题吗

TypeError at /book/
<Genre: Genre object> is not JSON serializable
/book处的
TypeError/
JSON不可序列化
您需要查看a)ChoiceField希望作为选项接收什么,b)values\u list()返回什么

a) 在
选项中,字段
需要“一个有效值列表,或一个
(键,显示名称)
元组列表”。在这种情况下,有效值将是类型的主键ID

b) 根据无参数的
values\u list()
返回“模型中的所有字段,按照它们声明的顺序。”

我认为您不可能因为使用
choices=Genre.objects.values\u 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))
如果您的
类型
模型中有一个字段可以成为一个好的“显示名称”,那么您可以执行以下操作:

class BookSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.ReadOnlyField(source = 'owner.username')
    genres = serializers.ChoiceField(choices=Genre.objects.values_list('pk', 'name'))
然而上述两个选项都存在一个问题,即在导入包含资源的文件时,将立即对查询集进行评估。(因为ChoiceField会立即将其转换为列表)

在进口时产生这种副作用是不好的做法。此外,由于每次启动服务器时只对其进行一次评估,因此当您更改类型时,这些选择将过时

幸运的是,有一个更好的选择:

这类似于Django中的ModelChoiceField。它有一个
queryset
参数,用于验证选项。。。但与ChoiceField不同,它知道不需要立即评估queryset。每次需要验证选择时,都会对其进行评估

所以你应该:

class BookSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.ReadOnlyField(source = 'owner.username')
    genres = serializers.PrimaryKeyRelatedField(queryset=Genre.objects.all())

您可以查看是否需要为关系字段上的选择自定义“显示名称”。

当模型已更改但未迁移时,我通常会收到此类错误。
试着这样做。这可能会有所帮助

我想使用ChoiceField,因为它会自动在期权调用中添加可用选项。我用PrimaryKeyRelatedField尝试了这种方法,但它不返回选项中的可用选项,而ChoiceField的问题与@Oonah My code:
activity\u type=serializers.ChoiceField(choices=ActivityType.objects.filter(primary\u activity=True)。value\u list(“id”,“name”)