django-taggit icon indicating copy to clipboard operation
django-taggit copied to clipboard

TypeError: Object of type _TaggableManager is not JSON serializable

Open mirodil1 opened this issue 2 years ago • 4 comments

I am using django-taggit, django-parler, django-parler-rest and django-rest-framework on my project and getting following errors when trying to get or add object.

  • When I create object on admin page it is not accepting tags and leaves field empty, if I create tags manually getting errorValueError: language_code can't be null, use translation.activate(..) when accessing translated models outside the request/response loop.
  • When trying to get objects through API, getting error TypeError: Object of type _TaggableManager is not JSON serializable

models.py

class Post(TimeStampedModel):
    translations = TranslatedFields(
      name = models.CharField(
          max_length=255,
          db_index=True,
      ),
      slug = models.SlugField(
          max_length=255,
          db_index=True,
          unique=True,
      )
      tags = TaggableManager(),
    )

serializer.py

class PostSerializer(TaggitSerializer, TranslatableModelSerializer):
    tags = TagListSerializerField()
    translations = TranslatedFieldsField(shared_model=Posts)
    
    class Meta:
        model = Posts
        fields = [
            "id",
            "name",
            "translations",
            "tags",
        ]

mirodil1 avatar Dec 27 '22 08:12 mirodil1

@mirodil1 do you have a full stack trace for these errors? this is not enough information for us to figure things out.

rtpg avatar Jan 08 '23 02:01 rtpg

@rtpg no atm, I guess the problem was with django-parler, it creates translations table and there is also field for django-taggit, in serializer it should be defined as tags=TagListSerializerField() , and for tags field in translations also should be TagListSerializerField() somehow.

mirodil1 avatar Jan 09 '23 17:01 mirodil1

Hi, I came across this issue as I got the same error when using tags with factory-boy (otherwise everything is working great, thanks!). Would be great if you could take another look at it.

I added the following to my existing factory class, as suggested in your docs:

@post_generation
def tags(self, create, extracted, **kwargs):
    if not create:
        return
    if extracted:
        self.tags.add(*extracted)

Then when I ran my tests, I got the following stack trace, in case that helps you figure out the problem:

self = <json.encoder.JSONEncoder object at 0x107460820>
o = <taggit.managers._TaggableManager object at 0x109af23a0>

    def default(self, o):
        """Implement this method in a subclass such that it returns
        a serializable object for ``o``, or calls the base implementation
        (to raise a ``TypeError``).
    
        For example, to support arbitrary iterators, you could
        implement default like this::
    
            def default(self, o):
                try:
                    iterable = iter(o)
                except TypeError:
                    pass
                else:
                    return list(iterable)
                # Let the base class default method raise the TypeError
                return JSONEncoder.default(self, o)
    
        """
>       raise TypeError(f'Object of type {o.__class__.__name__} '
                        f'is not JSON serializable')
E       TypeError: Object of type _TaggableManager is not JSON serializable

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/encoder.py:179: TypeError

rosamundm avatar Jul 16 '23 17:07 rosamundm

the solution for this issue in django-taggit is to import the built in TagListSerializerField from the django-taggit itself.

from taggit.serializers import TagListSerializerField, TaggitSerializer

class BlogSerializer(TaggitSerializer, serializers.ModelSerializer):
    tags = TagListSerializerField(required=False)

sarozpradhan64 avatar Jul 22 '24 16:07 sarozpradhan64