{"id":6601,"library":"django-solo","title":"django-solo","description":"Django Solo is a Python library that simplifies working with singleton models in Django applications. Singletons are database tables designed to hold only one row, often used for global settings or site-wide configurations that can be edited via the Django admin interface. It provides helper classes for models and admin, a template tag for easy retrieval, and supports caching. The library is actively maintained, with version 2.5.1 being the latest, and sees regular updates to support newer Django and Python versions.","status":"active","version":"2.5.1","language":"en","source_language":"en","source_url":"https://github.com/lazybird/django-solo/","tags":["django","singleton","admin","settings"],"install":[{"cmd":"pip install django-solo","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Core framework dependency for integration.","package":"Django","optional":false}],"imports":[{"symbol":"SingletonModel","correct":"from solo.models import SingletonModel"},{"symbol":"SingletonModelAdmin","correct":"from solo.admin import SingletonModelAdmin"},{"note":"Used as a template tag; `get_solo()` can also be called directly on the model class in Python.","symbol":"get_solo","correct":"{% load solo_tags %}\n{% get_solo 'app_label.ModelName' as config %}"}],"quickstart":{"code":"import os\nimport django\nfrom django.conf import settings\nfrom django.template import Context, Template\nfrom django.test import override_settings\n\n# Configure Django for a minimal setup\nsettings.configure(\n    INSTALLED_APPS=['solo', 'my_app'],\n    DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},\n    TEMPLATES=[{\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [],\n        'APP_DIRS': True,\n        'OPTIONS': {'context_processors': []}\n    }],\n    USE_I18N=True,\n    LANGUAGE_CODE='en-us',\n    ROOT_URLCONF='my_project.urls', # Placeholder for minimal config\n)\ndjango.setup()\n\n# Create a dummy app for the example\nwith open('my_app/__init__.py', 'w') as f: pass\nwith open('my_app/models.py', 'w') as f:\n    f.write(\n        \"\"\"from django.db import models\nfrom solo.models import SingletonModel\n\nclass SiteConfiguration(SingletonModel):\n    site_name = models.CharField(max_length=255, default='My Site')\n    maintenance_mode = models.BooleanField(default=False)\n\n    def __str__(self):\n        return \"Site Configuration\"\n\n    class Meta:\n        verbose_name = \"Site Configuration\"\n\"\"\"\n    )\nwith open('my_app/admin.py', 'w') as f:\n    f.write(\n        \"\"\"from django.contrib import admin\nfrom solo.admin import SingletonModelAdmin\nfrom my_app.models import SiteConfiguration\n\nadmin.site.register(SiteConfiguration, SingletonModelAdmin)\n\"\"\"\n    )\n\n# Simulate Django migrations (simplified for quickstart)\nfrom django.apps import apps\napps.app_configs['my_app'].models_module = __import__('my_app.models', fromlist=[''])\n\nfrom my_app.models import SiteConfiguration\n\n# Accessing the singleton instance\nconfig = SiteConfiguration.get_solo()\nprint(f\"Initial site name: {config.site_name}\")\n\n# Modifying and saving\nconfig.site_name = \"Updated Site Name\"\nconfig.maintenance_mode = True\nconfig.save()\n\n# Retrieve again to confirm (without caching enabled, this hits DB)\nupdated_config = SiteConfiguration.get_solo()\nprint(f\"Updated site name: {updated_config.site_name}\")\nprint(f\"Maintenance mode: {updated_config.maintenance_mode}\")\n\n# Example of using in a Django template (requires solo_tags to be loaded)\n# This is illustrative, full Django setup for templates is more involved.\n# For actual template rendering, you'd typically have a view and proper template loaders.\n# Let's simulate a template context and rendering here.\n\n@override_settings(TEMPLATES=[\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'APP_DIRS': True,\n        'OPTIONS': {'context_processors': []},\n    },\n])\ndef render_template_example():\n    from django.template import Context, Template\n    from django.apps import apps\n\n    # Manually register solo_tags for this isolated test if not auto-loaded\n    # In a real Django project, solo would be in INSTALLED_APPS and tags loaded automatically\n    apps.app_configs['solo'].models_module = __import__('solo.models', fromlist=[''])\n    apps.app_configs['solo'].admin_module = __import__('solo.admin', fromlist=[''])\n    apps.app_configs['solo'].templatetags_module = __import__('solo.templatetags', fromlist=[''])\n\n    template_string = \"\"\"\n    {% load solo_tags %}\n    {% get_solo 'my_app.SiteConfiguration' as site_config %}\n    <h1>Welcome to {{ site_config.site_name }}</h1>\n    {% if site_config.maintenance_mode %}\n        <p>Site is currently under maintenance.</p>\n    {% endif %}\n    \"\"\"\n    template = Template(template_string)\n    context = Context({})\n    rendered = template.render(context)\n    print(\"\\n--- Template Output ---\")\n    print(rendered)\n\nrender_template_example()\n\n# Cleanup dummy app files\nos.remove('my_app/__init__.py')\nos.remove('my_app/models.py')\nos.remove('my_app/admin.py')\nos.rmdir('my_app')","lang":"python","description":"Defines a singleton model and its admin integration. It demonstrates how to create, retrieve, modify, and save the singleton instance in Python, and how to access it within a Django template using the `get_solo` template tag. Remember to add `solo` (or `solo.apps.SoloAppConfig`) and your app to `INSTALLED_APPS` and run `makemigrations` and `migrate` for database setup."},"warnings":[{"fix":"Review `django-solo` release notes for specific version compatibility before upgrading. Upgrade Python/Django versions as needed to meet `django-solo`'s requirements.","message":"Older Python and Django versions are regularly dropped. Ensure your project's Python and Django versions are compatible with the django-solo version you are using. For example, Django-solo 2.2.0 dropped support for Python 3.7 and Django 4.0/4.1. Version 2.4.0 dropped support for Django <3.2 and simplified `default_app_config` removal.","severity":"breaking","affected_versions":">=2.2.0, >=2.4.0"},{"fix":"Upgrade to `django-solo` 2.4.0 or later, which includes a fix to disambiguate cache keys. If upgrading is not possible, ensure unique model names across your project or manage caching carefully.","message":"Prior to version 2.4.0, a potential cache key collision could occur for similarly named singleton models across different Django applications. This could lead to incorrect data retrieval from the cache.","severity":"gotcha","affected_versions":"<2.4.0"},{"fix":"To enable caching, configure your `CACHES` setting in `settings.py` and set `SOLO_CACHE` to the name of the desired cache backend (e.g., `SOLO_CACHE = 'default'`). Optionally, adjust `SOLO_CACHE_TIMEOUT` and `SOLO_CACHE_PREFIX`.","message":"Caching is disabled by default in `django-solo`. Every call to `get_solo()` will result in a database query unless caching is explicitly enabled and configured in your Django settings.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Add `singleton_instance_id = <your_desired_id>` to your `SingletonModel` definition. Ensure the chosen ID corresponds to an existing (or desired) single row in your database table.","message":"If migrating an existing model to a singleton model or if your `SingletonModel` might have pre-existing rows, it's recommended to set `singleton_instance_id` on the model explicitly (e.g., `singleton_instance_id = 1`) to ensure `django-solo` uses the correct instance.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Wrap calls to `get_solo()` in `ready()` within a `try-except` block to catch `OperationalError` or `ProgrammingError` and handle scenarios where the database table might not exist yet. Consider using a `post_migrate` signal instead for creating initial singleton instances.","message":"Calling `SiteConfiguration.get_solo()` directly within an `AppConfig.ready()` method can lead to `django.db.utils.OperationalError` if database migrations for the model have not yet been applied, particularly on first `migrate`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}