簡體   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