{"id":13419531,"url":"https://github.com/tatterdemalion/django-nece","last_synced_at":"2025-08-11T23:16:03.439Z","repository":{"id":56276822,"uuid":"49781798","full_name":"tatterdemalion/django-nece","owner":"tatterdemalion","description":"Content Translation Framework based on Postgresql's JSONB field","archived":false,"fork":false,"pushed_at":"2024-02-07T18:43:55.000Z","size":208,"stargazers_count":85,"open_issues_count":6,"forks_count":25,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-20T23:50:05.332Z","etag":null,"topics":["content","django","django-framework","i18n","jsonb","language","languages","postgres","postgresql","postgresql-database","translation","translations"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tatterdemalion.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-01-16T16:46:40.000Z","updated_at":"2025-05-09T07:22:25.000Z","dependencies_parsed_at":"2024-06-19T17:11:31.921Z","dependency_job_id":"190505bb-f2e6-4ac4-91d0-f1ac3fa198f4","html_url":"https://github.com/tatterdemalion/django-nece","commit_stats":{"total_commits":141,"total_committers":15,"mean_commits":9.4,"dds":"0.17021276595744683","last_synced_commit":"2d4784e5e5150b8443f196260e08e8de9f38ce02"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/tatterdemalion/django-nece","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatterdemalion%2Fdjango-nece","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatterdemalion%2Fdjango-nece/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatterdemalion%2Fdjango-nece/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatterdemalion%2Fdjango-nece/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tatterdemalion","download_url":"https://codeload.github.com/tatterdemalion/django-nece/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tatterdemalion%2Fdjango-nece/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269970124,"owners_count":24505469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["content","django","django-framework","i18n","jsonb","language","languages","postgres","postgresql","postgresql-database","translation","translations"],"created_at":"2024-07-30T22:01:17.299Z","updated_at":"2025-08-11T23:16:03.407Z","avatar_url":"https://github.com/tatterdemalion.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":".. image:: https://img.shields.io/travis/tatterdemalion/django-nece/master.svg\n    :target: https://travis-ci.org/tatterdemalion/django-nece\n\n.. image:: https://img.shields.io/coveralls/tatterdemalion/django-nece.svg\n    :target: https://coveralls.io/r/tatterdemalion/django-nece\n\n.. image:: https://img.shields.io/pypi/v/nece.svg\n    :target: https://pypi.python.org/pypi/nece\n\n.. image:: https://img.shields.io/pypi/pyversions/nece.svg\n    :target: https://pypi.python.org/pypi/nece/\n\n\nIMPORTANT NOTICE\n=====\n\nThis repository is not maintained anymore. Please feel free to fork. If you are interested, I will be happy to transfer the ownership and help with the ecosystem (travis, pip etc...) as much as I can.\n\n\nnece?\n=====\n\nIntroduction\n------------\n\n.. figure:: https://raw.githubusercontent.com/tatterdemalion/django-nece/master/images/nece.png\n   :alt: nece\n\nA “Content Translation Framework” using Postgresql’s jsonb field. It\nsimply sets and gets translations from a jsonb field called\n``translations``.\n\nWhy?\n~~~~\n\nYou might ask why you should use django-nece since there are other, and\nmore mature content translation frameworks like `django-hvad`_ and\n`django-modeltranslation`_. Both of them are good in some ways, worst in\nothers.\n\nFor instance, it is very hard for ``django-hvad`` users to get default\nlanguage if there is no corresponding translation for an object. And it\nholds translated values in a different table, so every translation query\nresults in another hit to the database.\n\nOn the other hand ``django-modeltranslation`` adds multiple additional\nfields for multiple languages. The number of fields inceases by the\nnumber of languages you need to support. At the end it becomes a huge\nchunk of an object if you need to add more than 20 languages.\n\n``nece?`` more or less works like the latter one with an important\ndifference. It uses Postgresql’s new ``JSONB`` field to hold translation\ninformation. And overrides the original one on query.\n\nDependencies\n------------\n\n::\n\n    postgresql \u003e= 9.4.5\n    Django \u003e= 1.9\n    psycopg2 \u003e= 2.5.4\n\n\nInstallation\n------------\n\nvia pypi:\n~~~~~~~~~\n\n::\n\n    pip install nece\n\nvia setup.py\n~~~~~~~~~~~~\n\n::\n\n    python setup.py install\n\nUsage\n-----\n\nLets say we have a model called ``Fruit``:\n\n::\n\n    from nece.models import TranslationModel\n\n    class Fruit(TranslationModel):\n        name = CharField(max_length=255)\n\n        def __str__(self):\n            return self.name\n      \n        class Meta:\n            translatable_fields = ('name',)\n\n``TranslationModel`` adds a jsonb field to this table and sets\ntranslations in a notation like the one below:\n\n::\n\n    {u'de_de': {u'name': u'Apfel'},\n     u'tr_tr': {u'name': u'elma'}}\n\nWhen we need the German translation we can simply choose the language\nand get the attribute as usual:\n\n::\n\n    \u003e\u003e f = Fruit.objects.get(name='apple')\n    \u003e\u003e print(f.name)\n    apple\n    \u003e\u003e f.language('de_de')\n    \u003e\u003e print(f.name)\n    Apfel\n\nYou can also filter out the ones containing any language translation:\n\n::\n\n    \u003e\u003e Fruit.objects.all()\n    [\u003cFruit: apple\u003e, \u003cFruit: pear\u003e, \u003cFruit: banana\u003e]\n    \u003e\u003e Fruit.objects.language('tr_tr')\n    [\u003cFruit: elma\u003e, \u003cFruit: armut\u003e]  # there is no translation for banana\n    \u003e\u003e Fruit.objects.language_or_default('tr_tr')\n    [\u003cFruit: elma\u003e, \u003cFruit: armut\u003e, \u003cFruit: banana\u003e]\n    \u003e\u003e Fruit.objects.language('tr_tr').filter(name='elma')\n    [\u003cFruit: elma\u003e]\n    \u003e\u003e Fruit.objects.language('tr_tr').get(name='elma')\n    \u003cFruit: elma\u003e\n\nUpdating translations\n~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    \u003e\u003e fruit._language_code\n    tr_tr\n    \u003e\u003e fruit.name\n    elma\n    \u003e\u003e fruit.translate(name='armut').save()\n    \u003e\u003e fruit.name\n    armut\n    \u003e\u003e fruit.language('en')\n    \u003e\u003e fruit.translate('it_it', name='pera')\n    \u003e\u003e fruit.language('it_it')\n    \u003e\u003e fruit.name\n    pera\n\nSettings\n--------\n\nTRANSLATIONS_DEFAULT\n~~~~~~~~~~~~~~~~~~~~\n\nDefault language code. Default value: ```en_us```\n\nTRANSLATIONS_MAP\n~~~~~~~~~~~~~~~~\n\nShortcuts for ```languagecode_countrycode``` notation. \n\nExample:\n\n::\n\n    TRANSLATIONS_MAP = {\n        \"en\": \"en_us\",\n        \"tr\": \"tr_tr\",\n        \"ar\": \"ar_sy\",\n        \"bg\": \"bg_bg\",\n        \"cs\": \"cs_cz\",\n        \"da\": \"da_dk\",\n        ...\n    }\n\n\nDefault:\n\n::\n\n    {'en': 'en_us'}\n\n\nTRANSLATIONS_FALLBACK\n~~~~~~~~~~~~~~~~~~~~~\n\nFallback language would be used if a translation is missing.\n\nExample:\n\n::\n    TRANSLATIONS_FALLBACK = {\n        'fr_ca': ['fr_fr'],\n        'en_us': ['en_gb'],\n    }\n\nAdmin panel\n--------\nUse `TranslatableModelAdmin` for pretty JSON editor (powered by `django-admin-json-editor`_).\n\n.. figure:: https://raw.githubusercontent.com/tatterdemalion/django-nece/master/images/admin.png\n   :alt: nece\n\nExample:\n\n.. code-block:: python\n\n   # settings.py\n   INSTALLED_APPS = [\n       ...\n       'django_admin_json_editor',\n       ...\n   ]\n\n   # admin.py\n   from nece.admin import TranslatableModelAdmin\n\n   class PlaceAdmin(TranslatableModelAdmin):\n       list_display = ('...')\n\n\nContributors \u0026 Thanks\n---------------------\n\n- `Erkan Ay`_\n- `Ayman Khalil`_\n- `Gönül Sabah`_\n- `Faruk Rahmet`_\n- `Mathieu Richardoz`_\n- `Marc Hertzog`_\n- `Alexey Kotenko`_\n\n`Change Log`_\n\n\n.. _django-hvad: https://github.com/kristianoellegaard/django-hvad\n.. _django-modeltranslation: https://github.com/deschler/django-modeltranslation\n.. _Erkan Ay: https://github.com/erkanay\n.. _Ayman Khalil: https://github.com/aymankh86\n.. _Gönül Sabah: https://github.com/gonulsabah\n.. _Faruk Rahmet: https://github.com/farukrahmet\n.. _Mathieu Richardoz: https://github.com/metamatik\n.. _Marc Hertzog: https://github.com/kemar\n.. _Alexey Kotenko: https://github.com/k0t3n\n.. _Change Log: https://github.com/tatterdemalion/django-nece/blob/master/CHANGELOG.md\n.. _django-admin-json-editor: https://github.com/abogushov/django-admin-json-editor\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftatterdemalion%2Fdjango-nece","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftatterdemalion%2Fdjango-nece","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftatterdemalion%2Fdjango-nece/lists"}