{"id":2004,"library":"django-taggit","title":"django-taggit","description":"django-taggit is a reusable Django application for simple, yet powerful, tagging. It provides a `TaggableManager` to easily add tags to any Django model. The current version is 6.1.0, and it maintains an active development and release cadence, supporting modern Django and Python versions.","status":"active","version":"6.1.0","language":"en","source_language":"en","source_url":"https://github.com/jazzband/django-taggit","tags":["django","tagging","model-utility"],"install":[{"cmd":"pip install django-taggit","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core framework dependency for the application.","package":"Django","optional":false}],"imports":[{"note":"Used to add a tag field to a Django model.","symbol":"TaggableManager","correct":"from taggit.managers import TaggableManager"},{"note":"Used to directly interact with the Tag model, e.g., for querying all tags.","symbol":"Tag","correct":"from taggit.models import Tag"}],"quickstart":{"code":"import os\nimport django\nfrom django.conf import settings\nfrom django.db import models\n\nsettings.configure(\n    INSTALLED_APPS=[\n        'django.contrib.auth',\n        'django.contrib.contenttypes',\n        'taggit',\n    ],\n    DATABASES={\n        'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}\n    },\n    SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-that-should-be-changed'),\n    DEFAULT_AUTO_FIELD='django.db.models.BigAutoField',\n)\ndjango.setup()\n\nfrom taggit.managers import TaggableManager\n\nclass Post(models.Model):\n    title = models.CharField(max_length=200)\n    content = models.TextField()\n    tags = TaggableManager()\n\n    def __str__(self):\n        return self.title\n\n# --- Example Usage ---\n\n# After migrations (run `python manage.py migrate` in a real project):\n# from django.core.management import call_command\n# call_command('migrate', interactive=False)\n\n# Create a post\npost1 = Post.objects.create(title='My First Post', content='Content goes here.')\npost1.tags.add('python', 'django', 'tutorial')\n\npost2 = Post.objects.create(title='Another Post', content='More content.')\npost2.tags.add('python', 'web-dev')\n\nprint(f\"Post 1 tags: {list(post1.tags.names())}\")\nprint(f\"Posts tagged with 'python': {Post.objects.filter(tags__name__in=['python']).count()}\")\nprint(f\"All tags: {list(TaggableManager().all_tags().names())}\")\n\n# Remove a tag\npost1.tags.remove('tutorial')\nprint(f\"Post 1 tags after removal: {list(post1.tags.names())}\")","lang":"python","description":"To quickly integrate `django-taggit`, install it, add 'taggit' to your `INSTALLED_APPS`, run migrations, and then add a `TaggableManager` field to your Django model. This example demonstrates basic model creation, tag assignment, filtering, and tag removal."},"warnings":[{"fix":"Ensure your project uses Python 3.9 or newer. Downgrade `django-taggit` to a 5.x version if Python 3.8 support is critical.","message":"As of `django-taggit` 6.1.0, Python 3.8 is no longer supported; Python 3.9+ is now required. While PyPI metadata may still show `>=3.8`, the official documentation and changelog confirm the updated requirement.","severity":"breaking","affected_versions":"6.1.0+"},{"fix":"If you relied on the previous unordered behavior or a specific custom ordering, you can explicitly set `ordering=[]` on your `TaggableManager` instance: `tags = TaggableManager(ordering=[])`.","message":"In `django-taggit` 6.0.0, the default ordering of tag items on instances changed to be by primary key (effectively creation date). Previously, tag items were not explicitly ordered, which could lead to inconsistent results.","severity":"breaking","affected_versions":"6.0.0+"},{"fix":"To enable case-insensitive tag lookups, add `TAGGIT_CASE_INSENSITIVE = True` to your Django `settings.py` file. This setting is `False` by default.","message":"Tag lookups are case-sensitive by default. Tags like 'Python' and 'python' will be treated as distinct tags.","severity":"gotcha","affected_versions":"All versions"},{"fix":"You often need to implement custom serializer fields or methods (e.g., `TagListSerializerField` from `taggit.serializers` or custom `serializers.SlugRelatedField`) to correctly handle tag input and output with DRF.","message":"When using `django-taggit` with Django REST Framework, the `TaggableManager` field does not behave like a simple list for serialization. Direct `ModelSerializer` usage for tags might lead to exceptions.","severity":"gotcha","affected_versions":"All versions"},{"fix":"When installing, always pin `django-taggit` to a compatible version for your Django installation (e.g., `pip install 'django-taggit<5'` for older Django) or ensure `Django` itself is pinned to avoid unexpected upgrades. This was fixed in `5.0.1`.","message":"In `django-taggit` 5.0.0, there was an issue where package metadata incorrectly stated `Django >=3.2`. This could lead to `pip` automatically upgrading Django to an incompatible version (e.g., Django 4.0 for a Django 2.2 project) upon `django-taggit` installation if version bounds were not specified.","severity":"breaking","affected_versions":"5.0.0"},{"fix":"Remove `'taggit'` from `INSTALLED_APPS` if you are providing your own custom tag models and ensure your custom models are correctly configured according to the 'Customizing taggit' documentation.","message":"If you wish to use custom Tag or Through models, you must remove `'taggit'` from your `INSTALLED_APPS` setting. Including it will create `django-taggit`'s default models, which might conflict or be redundant.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}