Search code examples
djangodjango-rest-frameworkdjango-taggit

Using Django-taggit and django-taggit-serializer with issue


I am trying to add tags in my model by taggit and taggit serializer. I making my API in rest framework. I followed the instruction(https://github.com/glemmaPaul/django-taggit-serializer) but it is still an issues:

"tags": [ "Invalid json list. A tag list submitted in string form must be valid json."]

/setting.py

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

/models.py

tags = TaggableManager(blank = True) 

/serializer.py

class JobSerializer(TaggitSerializer,serializers.HyperlinkedModelSerializer):

# tag serializer
tags = TagListSerializerField()

There is noting changed in the view.py.

thanks @ykh for helping me to solve this problem, but it comes to new situation with error:

when you want to initial the value:

hao,free

the outcome will be like that:

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

But when I intend to put updates into this value: it showed the Json file in rest framework automatically:

enter image description here

and if you put data to your api, the result will be:

enter image description here

The issue is that each time when I try to modify the instance which including the 'tag' in rest framework, brackets and line breaks were automatic attached added in 'tag' field, like the picture result shows


Update: It seems that I have solved this issue, the solution is overriding the create function in serializer:

using django-taggit-serializer. and

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

Solution

  • try:

    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()
    

    post tags with 'tags1,tags2'

    The original source code is :

    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
    

    the error is caused by json.loads(value) is not success and i don't konw which data type is excepted.