{ "info": { "author": "Branko Vukelic", "author_email": "branko@brankovukelic.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 2 - Pre-Alpha", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License" ], "description": "=================\ndjango-i18n-model\n=================\n\nAdding translations to Django models is a topic that has been discussed from a\nvast variety of angles, and yet still not very well defined. django-i18n-model\nis yet another solution for adding i18n to your models.\n\nIt is very similar to django-hvad_ in that it uses the actual database and\nmetaclasses to do its job, but unlike django-hvad, it does not modify the source\nmodel. Unlike django-modeltranslation_, and like django-hvad, django-i18n-models\ndoes not add any new fields to the source model.\n\nOne interesting library for handling i18n in models is django is django-lingua_.\nUnlike any of the database-backed solutions, it uses the gettext interface to\nfacilitate translation of model data. While we find lingua interesting in\nprinciple, we believe translation of database data should be kept in the\ndatabase (and lingua didn't work very well for us anyway).\n\nThe main advantage of using django-i18n-model is the ability to:\n\n1. Add custom fields to translations\n\n2. Ability to use South migrations\n\n3. Not necessary to modify your existing models\n\nKeep in mind that this library is fairly young so it still lacks many of the\nconvenience features such as automatic translation of fields. Those features \nare still being designed and are planned for future releases.\n\nBackwards incompatible changes\n==============================\n\nStarting with v0.0.8, unique field handling is changed. Unique fields will no\nlonger be unique across all translations, but just per language. Please file a\nbug report with a description of a use case if you know of a case where this\nbehavior is not desirable.\n\nOverview\n========\n\ndjango-i18n-model works by creating a completely separate model for translation.\nIt does so by obtaining information about the model fields from the source model\nand creating a clone with additional fields called ``i18n_language`` and\n``i18n_source``. It currently offers several ways of referencing the translation\nsource model and the set of fields to include in the translations.\n\nInstallation\n============\n\nInstall using pip or easy_install::\n\n pip install django-i18n-model\n\n easy_install django-i18n-model\n\nYou can also download the tarball and unpack it into your project directory.\n\nIf you want to use the supplied template tags, you also need to add the\n``i18N_model`` app to ``INSTALLED_APPS``.\n\nBasic usage\n===========\n\nTo create a new translation model, simply subclass the ``I18nModel`` class::\n\n from django.db import models\n from i18n_model.models import I18nModel\n\n\n class Source(models.Model):\n \"\"\" Your normal model \"\"\"\n title = models.CharField(max_length=20)\n body = models.TextField()\n date = models.DateField()\n\n class SourceI18N(I18nModel):\n class Meta:\n translation_fields = ('title', 'body')\n\nWith the above setup, a new model is created that is named ``SourceI18N`` and it\nwill contain the ``title``, ``body``, ``i18n_language`` and ``i18n_source``\nfields. The ``i18n_source`` is a foreign key to ``Source`` model.\n\n*New in 0.0.7:* The ``i18n_language`` field was limited to languages defined by\n``settings.LANGUAGES``. Since 0.0.7, the selection of languages no longer\nincludes the default language defined by ``settings.LANGUAGE_CODE``.\n\nOther than adding the 'I18N' suffix to the translation model name, you can also\nuse the ``source_model`` Meta option to reference the source model. For\nexample::\n\n class SourceTranslation(I18nModel):\n class Meta:\n source_model = Source\n translation_fields = ('title', 'body')\n\nThe ``source_model`` attribute can point to the class object directly, or it can\nuse a string name of the class (ex: ``'Source'``) or, if the model is in a\ndifferent app, you can also use the ``'app.Model'`` format commonly used in\nDjango. The following are all equivalent::\n\n class SourceTranslation(I18nModel):\n class Meta:\n source_model = Source\n\n\n class SourceTranslation(I18nModel):\n class Meta:\n source_model = 'Source'\n\n\n class SourceTranslation(I18nModel):\n class Meta:\n source_model = 'appname.Source'\n\nAdmin integration\n=================\n\nFrom day one, i18n-model was designed to allow conventional admin integration\nusing inline admin form sets. Since the translation model is a proper model,\nthis wasn't a big issue. However, this package now includes a mixin to help\nmanage the form set count and max count when adding inline form sets for\ntranslations.\n\nUsing the above example models, an admin module may look like this::\n\n from django import admin\n from i18n_model.admin import I18nInlineMixin\n from .models import Source, SourceI18N\n\n \n class SourceI18nInline(I18nInlineMixin, admin.StackedInline):\n model = Source\n\n\n class SourceAdmin(admin.ModelAdmin):\n inlines = [SourceI18nInline]\n\n\n admin.site.register(Source, SourceAdmin)\n\nThe admin inline mixin checks the source module's translations and creates\ninline formsets for missing ones. When translations exist for all languages\nlisted under ``settings.LANGUAGES``, it will create no further inline forms.\n\nThis feature is not tested on Django >= 1.6 yet. Please let me know if it works\nfor you.\n\nCreating translations\n=====================\n\nYou can create translations as usual by simply creating a new instance of the\n``*I18N`` model, or you can use the ``translate`` class method on the ``*I18N``\nclass. Here is an example of the latter using the above code::\n\n my_source = Source(title='Test', body='test', date=datetime.date.today())\n my_translation = SourceI18N.translate(\n my_source,\n 'sr',\n title='\u0422\u0435\u0441\u0442',\n body='\u0442\u0435\u0441\u0442'\n )\n\nGetting translations\n====================\n\nThe translations are obtained using the ``translate`` class method. You can\nobtain translations for a specific language by calling the ``translate``\nclass method without any keyword arguments::\n\n translation = SourceI18N.translate(my_source, 'sr')\n translation.title # >> '\u0422\u0435\u0441\u0442'\n translation.body # >> \u0442\u0435\u0441\u0442'\n\nIt is also possible to obtain translations directly from the source model. The\nforeign key on the translation model creates a ``translations`` property on the\nsource model. This property is an instance of ``I18nManager`` custom manager,\nand it behaves like a normal Django manager for most part. To get all\ntranslations for a given object::\n\n my_source.translations.all()\n\nTo get translations for a specific language, the manager has shortcut manager\nmethods that are named after locales::\n\n translation = my_source.translations.sr().get()\n\nGetting translation languages\n=============================\n\nIf you need to get a list of languages for which translations exist, you can do\nso using the ``get_available_languages()`` method. For example::\n\n my_source.translations.get_available_languages() # >> ['sr', 'it']\n\nThis has very little value under normal circumstances, and it does result in a\ndatabase lookup, but it is used in the admin area for determining the initial\nvalue of form sets.\n\nRetrieving translations programmatically\n========================================\n\nAlthough the hard-coded locale methods are useful in templates, you may\nsometimes need to retrieve translations with variable locale. In that case, you\nmay want to use the ``lang`` manager method instead. Here's an example::\n\n SourceI18N.objects.lang('de').all()\n\nor::\n\n my_source.translations.lang('de').get()\n\nUsing the ``lang`` method without any language code will filter languages for\nthe currently active language::\n\n translation.activate('de')\n my_source.translations.lang().get() # Gets translation for 'de' language\n\nThe ``current_language`` manager method is a deprecated alias for the last form.\n\nRetrieving a single translation object\n======================================\n\nThe custom manager object has a shortcut for retrieving a single translation\nobject, which may be very useful when used on related source objects. The method\nis named ``get_by_lang()`` and is called with an optional language code. The\nlanguage code defaults to the currently active language. Here's an example::\n\n my_source.translations.get_by_lang() # Retrieves 'de' translation\n my_source.translations.get_by_lang('es') # Retrieves 'es' translation\n\nThe added benefit of using this shortcut is that it reuses the existing\nqueryset, so it works well with methods like ``prefetch_related``.\n\nTemplate tags\n=============\n\nTo use the template tags first load the ``i18n_model`` library::\n\n {% load i18n_model %}\n\n``{% translate %}`` tag\n-----------------------\n\nTranslate tag is an assignment tag. It takes the source object, and returns a\ntranslation object that you can use in your template. For example::\n\n {% translate my_source as my_translation %}\n {{ my_translation.title }}\n {{ my_translation.body }}\n\nBy default, it uses the currently active language for looking up translation. It\nwill return the original source object if there is no matching translation.\n\nNote that non-translated fields from the original model are not copied to the\ntranslation. For non-translated fields, always use the original.\n\n``{% translate_url [path] [language] %}`` tag\n---------------------------------------------\n\nIf you are using i18n in your URLs, you may sometimes need to obtain a\ntranslated URL. This tag gives you that ability. The tag accepts an optional\npath parameter which defaults to the current path. You must wrap it in the\nDjago's built-in ``{% language %}`` tag to get translations for different\nlanguages or use the language parameter. Here is an example::\n\n {% language 'es' %}\n {% translate_url %} current URL in Spanish\n {% endlanguage %}\n\n {% translate_url language='es' %} Same as above\n\n {% language 'es' %}\n {% translate_url object.get_absolute_path %} Object's URL in Spanish\n {% endlanguage %}\n\n {% translate_url object.get_absolute_path 'es' %} Same as above\n\n.. _django-hvad: http://django-hvad.readthedocs.org/en/latest/index.html\n.. _django-modeltranslation: https://github.com/deschler/django-modeltranslation\n.. _django-lingua: http://code.google.com/p/django-lingua/\n", "description_content_type": null, "docs_url": null, "download_url": "https://bitbucket.org/Lacrymology/django-i18n-model/downloads", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://bitbucket.org/Lacrymology/django-i18n-model", "keywords": null, "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "django-i18n-model", "package_url": "https://pypi.org/project/django-i18n-model/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-i18n-model/", "project_urls": { "Download": "https://bitbucket.org/Lacrymology/django-i18n-model/downloads", "Homepage": "https://bitbucket.org/Lacrymology/django-i18n-model" }, "release_url": "https://pypi.org/project/django-i18n-model/0.0.9/", "requires_dist": null, "requires_python": null, "summary": "Translations for Django models", "version": "0.0.9" }, "last_serial": 1312800, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "6dd66d1c4d6192e5a2b68c4a4472cae5", "sha256": "4df9b5dc8c36cab04c22ae96a1395d55662d102d02b19ede276ce62e81bf1750" }, "downloads": -1, "filename": "django-i18n-model-0.0.1.tar.gz", "has_sig": false, "md5_digest": "6dd66d1c4d6192e5a2b68c4a4472cae5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6254, "upload_time": "2013-06-01T15:11:06", "url": "https://files.pythonhosted.org/packages/54/46/dcea6fba19a2678ea192666970a246d0e86b5abb8b595761fe0907baa25c/django-i18n-model-0.0.1.tar.gz" }, { "comment_text": "", "digests": { "md5": "d3b449709fcfcbeed7a772daff783dd1", "sha256": "1ec8988da4f119d8d808395b13317374e5da1addce4c0f2f897febb9b3663c0b" }, "downloads": -1, "filename": "django-i18n-model-0.0.1.zip", "has_sig": false, "md5_digest": "d3b449709fcfcbeed7a772daff783dd1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9090, "upload_time": "2013-06-01T15:02:01", "url": "https://files.pythonhosted.org/packages/0a/cf/bc5006df1287cb7912e54cd53a9b2ff3c8f579ff1d4717bb60e7109a9f62/django-i18n-model-0.0.1.zip" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "0d970cdc4bd8d19515e063d2e338e40c", "sha256": "b27f8cce3cdf810a40122aa668fa3270d7f166fe91e86205aecb7af9643d456a" }, "downloads": -1, "filename": "django-i18n-model-0.0.2.tar.gz", "has_sig": false, "md5_digest": "0d970cdc4bd8d19515e063d2e338e40c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6335, "upload_time": "2013-06-01T15:36:05", "url": "https://files.pythonhosted.org/packages/08/98/5e8cb303963cf3d26e003ecb5cfe23a10ff8a643342950edfb2bb38f60ad/django-i18n-model-0.0.2.tar.gz" }, { "comment_text": "", "digests": { "md5": "d312522146e659ba3996dd50bcf5cf0d", "sha256": "27e195076d6e98c979dc998b43f0a7b18dfbb18f68179c64592d2d4226593c52" }, "downloads": -1, "filename": "django-i18n-model-0.0.2.zip", "has_sig": false, "md5_digest": "d312522146e659ba3996dd50bcf5cf0d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7462, "upload_time": "2013-06-01T15:36:13", "url": "https://files.pythonhosted.org/packages/87/c1/82d2cb4d447c5b412928ab267c1a460c89169044ea7bdaa4683562d9e223/django-i18n-model-0.0.2.zip" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "40fcf8332c7f75071d34698b11e90408", "sha256": "b0c528727308751116308b863069fbd814714ea6c24afc4c65ce197175cdde37" }, "downloads": -1, "filename": "django-i18n-model-0.0.3.tar.gz", "has_sig": false, "md5_digest": "40fcf8332c7f75071d34698b11e90408", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7130, "upload_time": "2013-06-02T14:48:30", "url": "https://files.pythonhosted.org/packages/82/52/af6f4b11d7783e7a7e97cc1d4ab5fd10b3ba7be02b995fba41b58e582902/django-i18n-model-0.0.3.tar.gz" }, { "comment_text": "", "digests": { "md5": "52a63e81aeb7f45489f5954eb15e32b9", "sha256": "f6918d28b20da5c726a69262b1bbda4bced3f11173bbdba546004e8e9b1c558c" }, "downloads": -1, "filename": "django-i18n-model-0.0.3.zip", "has_sig": false, "md5_digest": "52a63e81aeb7f45489f5954eb15e32b9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8826, "upload_time": "2013-06-02T14:48:43", "url": "https://files.pythonhosted.org/packages/ed/8f/59906794311d68a22f909de69b91a463e9e9c85a1c7fab308b396752b22c/django-i18n-model-0.0.3.zip" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "e744ec07ad640d12f35734b5e5a1811e", "sha256": "88907994f96a1cbf615a152ac1886ee4674435637c7c52955f9f3119841d615b" }, "downloads": -1, "filename": "django-i18n-model-0.0.4.tar.gz", "has_sig": false, "md5_digest": "e744ec07ad640d12f35734b5e5a1811e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7262, "upload_time": "2013-06-03T18:58:32", "url": "https://files.pythonhosted.org/packages/a5/0e/0a67a41e90afcc1eb37a46f6d19f73b20fb8e2fbf55fa05f230c89d3af0d/django-i18n-model-0.0.4.tar.gz" }, { "comment_text": "", "digests": { "md5": "57585c86cb68abced79d2233312cfe09", "sha256": "5773ebbac62bc5607faad1fdba333fff6076df199db436e37f1e3715bae6c843" }, "downloads": -1, "filename": "django-i18n-model-0.0.4.zip", "has_sig": false, "md5_digest": "57585c86cb68abced79d2233312cfe09", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8979, "upload_time": "2013-06-03T18:58:39", "url": "https://files.pythonhosted.org/packages/d0/f5/cccc138e580cda7b4ad7e4bc30328e1ba32935316daf846323874f610a08/django-i18n-model-0.0.4.zip" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "e22fb7f16c499ae06d9a29e7f187a4dd", "sha256": "af67cccf7483c3a4e023c4f549b9dede4a525213da2bd5f6439989bff54f37b0" }, "downloads": -1, "filename": "django-i18n-model-0.0.5.tar.gz", "has_sig": false, "md5_digest": "e22fb7f16c499ae06d9a29e7f187a4dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7286, "upload_time": "2013-06-04T14:27:18", "url": "https://files.pythonhosted.org/packages/c1/76/2aafc984b680d04f0fc6463c00aa4535280c5612ba140f96b1a9c6a3f704/django-i18n-model-0.0.5.tar.gz" }, { "comment_text": "", "digests": { "md5": "1e9348979156b18f83355efd76f4bfd3", "sha256": "4188d8003fd33975d6d6cf20544f8a9b673536c4fef89936afd5ed5b854eee2e" }, "downloads": -1, "filename": "django-i18n-model-0.0.5.zip", "has_sig": false, "md5_digest": "1e9348979156b18f83355efd76f4bfd3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9008, "upload_time": "2013-06-04T14:27:25", "url": "https://files.pythonhosted.org/packages/d6/25/5fd0e1173203f70f7246d17d14ad98df602b47bb43db7ad732f517641819/django-i18n-model-0.0.5.zip" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "424ea01788d280a41599b5966dca61fc", "sha256": "515d1a7b6e091342cf54b0f2496443d25a28ed2100b0b040028ada63c0932c1f" }, "downloads": -1, "filename": "django-i18n-model-0.0.6.tar.gz", "has_sig": false, "md5_digest": "424ea01788d280a41599b5966dca61fc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7839, "upload_time": "2013-06-05T12:31:20", "url": "https://files.pythonhosted.org/packages/7b/97/fce5c56a2f1d545803beb10022df20f00ca7c7944cf987496e0d670d13a9/django-i18n-model-0.0.6.tar.gz" }, { "comment_text": "", "digests": { "md5": "4b0569c593937a88f630717665653a1f", "sha256": "374858d507144ffa2640ef3dd20880941aa7d4d26f6086e3439b0a4501fbd193" }, "downloads": -1, "filename": "django-i18n-model-0.0.6.zip", "has_sig": false, "md5_digest": "4b0569c593937a88f630717665653a1f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9522, "upload_time": "2013-06-05T12:31:28", "url": "https://files.pythonhosted.org/packages/69/24/b1ea90271b2a8e9ea6f0d76609e96f5578e84ec5668cc2f0abccc4e27b48/django-i18n-model-0.0.6.zip" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "285ac52e84c579249c74d62b66644f10", "sha256": "545e9d4b25844e62c70ef6ab0485aa4eef1b3ad1450705fdcf8527874acb7beb" }, "downloads": -1, "filename": "django-i18n-model-0.0.7.tar.gz", "has_sig": false, "md5_digest": "285ac52e84c579249c74d62b66644f10", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8206, "upload_time": "2013-06-07T14:36:29", "url": "https://files.pythonhosted.org/packages/d1/ad/95dad17bfcec639c076bd3ecce5addf6e8db7d86c40b3f4c2581a7b1508a/django-i18n-model-0.0.7.tar.gz" }, { "comment_text": "", "digests": { "md5": "b9777e73b9badfe51b5fd7adceb66063", "sha256": "92097603688e6ae79cd80dcc1f22addbbab995df04ddfb4d997658a9647de93a" }, "downloads": -1, "filename": "django-i18n-model-0.0.7.zip", "has_sig": false, "md5_digest": "b9777e73b9badfe51b5fd7adceb66063", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9971, "upload_time": "2013-06-07T14:36:36", "url": "https://files.pythonhosted.org/packages/8d/01/9f1ec7528f67e58ba516e56b858e297f8f7f65206c9d4fe40c1551a98c87/django-i18n-model-0.0.7.zip" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "cb22ac4efcb41ca624a68ad0171495f9", "sha256": "500aa60f60c54b2b05120b58e57ca63e4f985d308b1f0ea17e4ff35405fb4ded" }, "downloads": -1, "filename": "django-i18n-model-0.0.8.tar.gz", "has_sig": false, "md5_digest": "cb22ac4efcb41ca624a68ad0171495f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9302, "upload_time": "2013-12-12T15:18:50", "url": "https://files.pythonhosted.org/packages/06/79/d172016e7267d086f19955a695195328f97bdfd5427f7d6af39ae59a90ef/django-i18n-model-0.0.8.tar.gz" }, { "comment_text": "", "digests": { "md5": "988ea70a41e29204be17497117622402", "sha256": "b7c97dc4eb4077cbe7c14acbcb8c03fceae080a03bf8e026f6476f5c9e0b727a" }, "downloads": -1, "filename": "django-i18n-model-0.0.8.zip", "has_sig": false, "md5_digest": "988ea70a41e29204be17497117622402", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11448, "upload_time": "2013-12-12T15:19:03", "url": "https://files.pythonhosted.org/packages/ba/b7/9e4e39de0e4eedc1415ec6f8227db736a5b3e71da740b3318765f282ae93/django-i18n-model-0.0.8.zip" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "67829dd1dbccca8a56fc7abff80f9107", "sha256": "ed4a0b341b66b2463b318ad04b4ee1167aa778b1415cc8c6c7d9dfea12a5ef6b" }, "downloads": -1, "filename": "django-i18n-model-0.0.9.tar.gz", "has_sig": false, "md5_digest": "67829dd1dbccca8a56fc7abff80f9107", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9543, "upload_time": "2014-11-19T12:48:11", "url": "https://files.pythonhosted.org/packages/0b/60/8c927b1c62a061a55d4942a45984377569868df3e2e24c5575dae14d9b07/django-i18n-model-0.0.9.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "67829dd1dbccca8a56fc7abff80f9107", "sha256": "ed4a0b341b66b2463b318ad04b4ee1167aa778b1415cc8c6c7d9dfea12a5ef6b" }, "downloads": -1, "filename": "django-i18n-model-0.0.9.tar.gz", "has_sig": false, "md5_digest": "67829dd1dbccca8a56fc7abff80f9107", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9543, "upload_time": "2014-11-19T12:48:11", "url": "https://files.pythonhosted.org/packages/0b/60/8c927b1c62a061a55d4942a45984377569868df3e2e24c5575dae14d9b07/django-i18n-model-0.0.9.tar.gz" } ] }