繁体   English   中英

使用 Django-taggit 和 django-taggit-serializer 有问题

[英]Using Django-taggit and django-taggit-serializer with issue

我正在尝试通过 taggit 和 taggit 序列化程序在我的 model 中添加标签。 我在 rest 框架中制作了我的 API。 我按照说明( https://github.com/glemmaPaul/django-taggit-serializer ),但它仍然是一个问题:

"tags": [ "无效的 json 列表。以字符串形式提交的标签列表必须是有效的 json。"]

/设置.py

INSTALLED_APPS = [
  [...]
'rest_framework',
'taggit',
'taggit_serializer',
]

/模型.py

tags = TaggableManager(blank = True) 

/序列化程序.py

class JobSerializer(TaggitSerializer,serializers.HyperlinkedModelSerializer):

# tag serializer
tags = TagListSerializerField()

view.py 中的注意事项发生了变化。

感谢@ykh 帮助我解决了这个问题,但是遇到了错误的新情况:

当你想初始化值时:

hao,free

结果将是这样的:

 "tags": [
    "hao",
    "free"
],

但是当我打算对这个值进行更新时:它会自动显示 rest 框架中的 Json 文件:

在此处输入图像描述

如果您将数据放入您的 api,结果将是:

在此处输入图像描述

问题是,每次我尝试在 rest 框架中修改包含“标签”的实例时,都会在“标签”字段中自动附加括号和换行符,如图所示


更新:似乎我已经解决了这个问题,解决方案是覆盖序列化程序中的 create function:

使用 django-taggit-serializer。

    def create(self, validated_data):
    tags = validated_data.pop('tags')
    instance = super(JobSerializer, self).create(validated_data)
    instance.tags.set(*tags)
    return instance

尝试:

import six

class NewTagListSerializerField(TagListSerializerField):
    def to_internal_value(self, value):
        if isinstance(value, six.string_types):
            value = value.split(',')

        if not isinstance(value, list):
            self.fail('not_a_list', input_type=type(value).__name__)

        for s in value:
            if not isinstance(s, six.string_types):
                self.fail('not_a_str')

            self.child.run_validation(s)
        return value

class JobSerializer(TaggitSerializer,serializers.HyperlinkedModelSerializer):

    tags = NewTagListSerializerField()

发布带有“ tags1,tags2 ”的标签

原始源代码是:

def to_internal_value(self, value):
    if isinstance(value, six.string_types):
        if not value:
            value = "[]"
        try:
            value = json.loads(value)
        except ValueError:
            self.fail('invalid_json')

    if not isinstance(value, list):
        self.fail('not_a_list', input_type=type(value).__name__)

    for s in value:
        if not isinstance(s, six.string_types):
            self.fail('not_a_str')

        self.child.run_validation(s)

    return value

该错误是由json.loads(value)引起的,我不知道哪种数据类型被排除在外。

更正上面的答案,因为 Ykh 的解决方案不正确,当我想以 JSON 格式更新我的标签时(我得到了 \\r \\m \\ 符号)

import json

class NewTagListSerializerField(TagListSerializerField):
    def to_internal_value(self, value):
        if isinstance(value, six.string_types):
            if not value:
                value = "[]"
            try:
                if(type(value) == str):
                    if(value.__contains__('"') == True):
                        value = json.loads(value)
                    else:
                        value = value.split(',')

            except ValueError:
                self.fail('invalid_json')

        if not isinstance(value, list):
            self.fail('not_a_list', input_type=type(value).__name__)

        for s in value:
            if not isinstance(s, six.string_types):
                self.fail('not_a_str')

            self.child.run_validation(s)

        return value

我在编写单元测试时遇到了这个问题。 这是因为我用来存储 POST 数据的 python 字典在内部转换为 QueryDict。 这通常发生在 Django 将 POST 视为application/x-www-form-urlencoded类型的内容时,例如通过 HTML 表单发送的内容。

我认为TagListSerializerField期待 json,所以当它的to_internal_value被调用时,正在接收不正确的数据并且它失败并出现“无效的 json 列表......”错误。

简而言之,这是我必须做的。

data = {"tags": ["tag1", "tag2"]}
response = self.client.post('/api/endpoint/', json.dumps(data), content_type='application/json')

也就是说,需要将数据转换为json,并且需要设置内容类型。 在我的示例中, self.client是来自rest_framework.test APIClient

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM