{ "info": { "author": "\u0141ukasz Langa", "author_email": "lukasz@langa.pl", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Framework :: Django", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "==========\ndj.choices\n==========\n\n.. image:: https://travis-ci.org/ambv/dj.choices.png\n :target: https://travis-ci.org/ambv/dj.choices\n\nThis is a much clearer way to specify choices for fields in models and forms.\nA basic example::\n\n >>> from dj.choices import Choices\n >>> class Gender(Choices):\n ... _ = Choices.Choice\n ...\n ... male = _(\"Male\")\n ... female = _(\"Female\")\n ...\n >>> Gender()\n [(1, u'Male'), (2, u'Female')]\n >>> Gender.male\n \n >>> Gender.female\n \n >>> Gender.male.id\n 1\n >>> Gender.male.desc\n u'Male'\n >>> Gender.male.raw\n 'Male'\n >>> Gender.male.name\n u'male'\n >>> Gender.from_name(\"male\")\n \n >>> Gender.id_from_name(\"male\")\n 1\n >>> Gender.raw_from_name(\"male\")\n 'Male'\n >>> Gender.desc_from_name(\"male\")\n u'Male'\n >>> Gender.name_from_id(2)\n 'female'\n >>> Gender.name_from_id(3)\n Traceback (most recent call last):\n ...\n ValueError: Nothing found for '3'.\n >>> Gender.from_name(\"perez\")\n Traceback (most recent call last):\n ...\n ValueError: Nothing found for 'perez'.\n\nYou define a class of choices, specifying each choice as a class attribute.\nThose attributes are ``int`` subclasses, numbered automatically starting with\n1. The class provides several features which support the DRY principle:\n\n * An object instantiated from the choices class is basically a list of ``(id,\n localized_description)`` pairs straight for consumption by Django.\n\n * Each attribute defined can be retrieved directly from the class.\n\n * Metadata (e.g. attribute name, raw and localized description, numeric ID) of\n each attribute is accessible.\n\n * Choices which are suffixed by ``_`` to avoid clashing with Python keywords\n have this suffix automatically removed in their ``.name`` attributes\n\n * Lookup functions are available to help getting attributes or their metadata.\n\n.. note::\n The ``_ = Choices.Choice`` trick makes it possible for ``django-admin.py\n makemessages`` to find each choice description and include it in ``.po``\n files for localization. It masks ugettext only in the scope of the class so\n the rest of the module can safely use ugettext or ugettext_lazy. Having to\n specify ``_`` each time is not a particularly pretty solution but it's\n explicit. Suggestions for a better approach are welcome.\n\nGrouping choices\n----------------\n\nOne of the worst problems with choices is their weak extensibility. For\ninstance, an application defines a group of possible choices like this::\n\n >>> class License(Choices):\n ... _ = Choices.Choice\n ...\n ... gpl = _(\"GPL\")\n ... bsd = _(\"BSD\")\n ... proprietary = _(\"Proprietary\")\n ...\n >>> License()\n [(1, u'GPL'), (2, u'BSD'), (3, u'Proprietary')]\n\nAll is well until the application goes live and after a while the developer\nwants to include LGPL. The natural choice would be to add it after ``gpl`` but\nwhen we do that, the indexing would break. On the other hand, adding the new\nentry at the end of the definition looks ugly and makes the resulting combo\nboxes in the UI sorted in a counter-intuitive way. Grouping lets us solve this\nproblem by explicitly defining the structure within a class of choices::\n\n >>> class License(Choices):\n ... _ = Choices.Choice\n ...\n ... COPYLEFT = Choices.Group(0)\n ... gpl = _(\"GPL\")\n ...\n ... PUBLIC_DOMAIN = Choices.Group(100)\n ... bsd = _(\"BSD\")\n ...\n ... OSS = Choices.Group(200)\n ... apache2 = _(\"Apache 2\")\n ...\n ... COMMERCIAL = Choices.Group(300)\n ... proprietary = _(\"Proprietary\")\n ...\n >>> License()\n [(1, u'GPL'), (101, u'BSD'), (201, u'Apache 2'), (301, u'Proprietary')]\n\nThis enables the developer to include more licenses of each group later on::\n\n >>> class License(Choices):\n ... _ = Choices.Choice\n ...\n ... COPYLEFT = Choices.Group(0)\n ... gpl_any = _(\"GPL, any\")\n ... gpl2 = _(\"GPL 2\")\n ... gpl3 = _(\"GPL 3\")\n ... lgpl = _(\"LGPL\")\n ... agpl = _(\"Affero GPL\")\n ...\n ... PUBLIC_DOMAIN = Choices.Group(100)\n ... bsd = _(\"BSD\")\n ... public_domain = _(\"Public domain\")\n ...\n ... OSS = Choices.Group(200)\n ... apache2 = _(\"Apache 2\")\n ... mozilla = _(\"MPL\")\n ...\n ... COMMERCIAL = Choices.Group(300)\n ... proprietary = _(\"Proprietary\")\n ...\n >>> License()\n [(1, u'GPL, any'), (2, u'GPL 2'), (3, u'GPL 3'), (4, u'LGPL'),\n (5, u'Affero GPL'), (101, u'BSD'), (102, u'Public domain'),\n (201, u'Apache 2'), (202, u'MPL'), (301, u'Proprietary')]\n\nNote the behaviour:\n\n * the developer renamed the GPL choice but its meaning and ID remained stable\n\n * BSD, Apache and proprietary choices have their IDs unchanged\n\n * the resulting class is self-descriptive, readable and extensible\n\nAs a bonus, the explicitly specified groups can be used when needed::\n\n >>> License.COPYLEFT\n \n >>> License.gpl2 in License.COPYLEFT.choices\n True\n >>> [(c.id, c.desc) for c in License.COPYLEFT.choices]\n [(1, u'GPL, any'), (2, u'GPL 2'), (3, u'GPL 3'), (4, u'LGPL'),\n (5, u'Affero GPL')]\n\n``ChoiceField``\n---------------\n\nChoices can be used with generic ``IntegerField`` and ``CharField`` instances.\nWhen you do that though, some minor API deficiencies show up fairly quickly.\nFirst, when you define the field, you have to instanciate the choices class and\nthe default value has to be converted to the proper type explicitly::\n\n color = models.IntegerField(choices=Color(), default=Color.green.id)\n\nSecond, when getting the attribute back from a model, it has to be converted to\na Choice instance to do anything interesting with it::\n\n >>> obj = Model.objects.get(pk=3)\n >>> obj.color\n 3\n >>> Color.from_id(obj.color)\n \n\nTo overcome those problems a ``ChoiceField`` is available in the\n``dj.choices.fields`` package. It is based on integers on the database level but\nthe API exposes ``Choice`` instances. This helps both on the definition side::\n\n color = ChoiceField(choices=Color, default=Color.green)\n\nand on the access side::\n\n >>> obj = Model.objects.get(pk=3)\n >>> obj.color\n \n >>> obj.color = Color.green\n >>> obj.save()\n >>> Model.objects.get(pk=3).color\n \n\nFor rendering forms, the field coerces to integer values. That also means that\nwherever ``Choice`` instances are accepted, integers are also fine.\n\nAdvanced functionality\n----------------------\n\nFiltering\n~~~~~~~~~\n\nThe developer can specify all possible choices for future use and then filter\nout only the currently applicable values on choices creation::\n\n >>> class Language(Choices):\n ... _ = Choices.Choice\n ...\n ... de = _(\"German\")\n ... en = _(\"English\")\n ... fr = _(\"French\")\n ... pl = _(\"Polish\")\n ...\n >>> Language()\n [(1, u'German'), (2, u'English'), (3, u'French'), (4, u'Polish')]\n >>> Language(filter=(\"en\", \"pl\"))\n [(2, u'English'), (4, u'Polish')]\n\nThis has the great advantage of keeping the IDs and sorting intact.\n\nCustom item format\n~~~~~~~~~~~~~~~~~~\n\nOne can also change how the pairs are constructed by providing a factory\nfunction. For instance, to use the class of choices defined above for the\n``LANGUAGES`` setting in ``settings.py``, one could specify::\n\n >>> Language(item=lambda choice: (choice.name, choice.raw))\n [(u'de', 'German'), (u'en', 'English'), (u'fr', 'French'),\n (u'pl', 'Polish')]\n\nExtra attributes on choices\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nEach choice can receive extra arguments using the ``extra()`` method::\n\n >>> class Python(Choices):\n ... _ = Choices.Choice\n ...\n ... cpython = _(\"CPython\").extra(language='C')\n ... pypy = _(\"PyPy\").extra(language='Python')\n ... jython = _(\"Jython\").extra(language='Java')\n ... iron_python = _(\"IronPython\").extra(language='C#')\n\nThis adds a ``language`` attribute to each choice so you can get it back like\nthis::\n\n >>> Python.jython.language\n 'Java'\n\nThis enables polymorphic attribute access later on when using models or forms.\nFor instance, suppose you have a simple model like::\n\n >>> class Library(models.Model):\n ... name = models.CharField(max_length=100)\n ... python_kind = models.IntegerField(choices=Python(), default=Python.cpython.id)\n\nIn that case to get the implementation language back you'd do::\n\n >>> library = Library.objects.get(name='dj.choices')\n >>> Python.from_id(library.python_kind).language\n 'C'\n\nThat frees your user code of any conditionals or dictionaries that depend on the\nstate of the choices class. If you would add another choice to it, no user code\nneeds to be changed to support it. This also supports the DRY principle because\nthe choices class becomes the single place where configuration of that kind is\nheld.\n\nExtra attributes on choice groups\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nUnsurprisingly, choice groups can have extra attributes as well. They are then\ninherited by choices in such a group and can be overriden if necessary. For\ninstance::\n\n >>> class ProfileChange(Choices):\n ... _ = Choices.Choice\n ...\n ... USER = Choices.Group(0).extra(icon='bookkeeping.png', is_public=True)\n ... email = _(\"e-mail\").extra(is_public=False)\n ... first_name = _(\"first name\")\n ... last_name = _(\"last name\")\n ...\n ... BASIC_INFO = Choices.Group(10).extra(icon='bookkeeping.png', is_public=True)\n ... birth_date = _(\"birth date\").extra(icon='calendar.png')\n ... gender = _(\"gender\").extra(icon='male_female.png')\n ... country = _(\"country\")\n ... city = _(\"city\")\n ...\n ... CONTACT_INFO = Choices.Group(20).extra(icon='contactbook.png', is_public=False)\n ... skype = _(\"Skype ID\")\n ... icq = _(\"ICQ number\")\n ... msn = _(\"MSN login\")\n ... xfire = _(\"X-Fire login\")\n ... irc = _(\"IRC info\").extra(is_public=True)\n\nIn that case proper inheritance takes place::\n\n >>> ProfileChange.first_name.is_public\n True\n >>> ProfileChange.email.is_public\n False\n >>> ProfileChange.country.icon\n 'bookkeeping.png'\n >>> ProfileChange.birth_date.icon\n 'calendar.png'\n\n\nPredefined choices\n------------------\n\nThere are several classes of choices which are very common in web applications\nso they are provided already: ``Country``, ``Gender`` and ``Language``.\n\nHow do I run the tests?\n-----------------------\n\nThe easiest way would be to run::\n\n $ DJANGO_SETTINGS_MODULE=\"dj._choicestestproject.settings\" django-admin.py test\n\nChange Log\n----------\n\n0.11.0\n~~~~~~\n\n* Drop compatibility for Django < 1.4 and Python 2.6\n\n* Add support for Django 1.9 and 1.10 (use ``from_db_value`` instead of ``SubfieldBase``)\n\n* Add support for Python 3.5\n\n0.10.0\n~~~~~~\n\n* Works and tests run on Django 1.6 and Django 1.7; now tested with\n Python 3.4 as well\n\n0.9.2\n~~~~~\n\n* Python 2.6 is now supported as well thanks to Carl van Tonder\n\n0.9.1\n~~~~~\n\n* Long overdue Python 3 support (considered experimental)\n\n0.9.0\n~~~~~\n\n* Choices are now ``int`` subclasses so you can use a choice directly instead of\n ``choice.id`` and ``int(choice)`` is always safe\n\n* ``unicode(choice)`` is now equivalent to ``choice.desc``\n\n* Fixed ``get_FIELD_display()`` on models with ``ChoiceFields``\n\n0.8.6\n~~~~~\n\n* Values outside of defined choices for a ``ChoiceField`` now correctly display\n validation errors instead of throwing exceptions; fixes `issue #2\n `_\n\n* ``ChoiceField`` can have ``default=None``\n\n* Fixed regression from 0.8.5 where ``__gt(e)`` and ``__lt(e)`` couldn't be used\n on ``ChoiceField`` lookups\n\n* Minor refinements\n\n0.8.5\n~~~~~\n\n* ``ChoiceField`` is now correctly South-migrable\n\n* Models with ``ChoiceFields`` can now use ``__in``, ``__range`` and\n ``__isnull`` lookups on them; fixes `issue #1\n `_\n\n\n0.8.4\n~~~~~\n\n* proper ChoiceField support if the underlying ``IntegerField`` returns\n a ``long`` instead of an ``int``\n\n* minor ``__unicode__`` corrections for byte strings\n\n0.8.3\n~~~~~\n\n* ``MANIFEST.in`` was previously missing which made the source distribution hard\n to install\n\n0.8.2\n~~~~~\n\n* ``ChoiceField`` introduced\n\n* extra attribute injection API is now public and documented\n\n0.8.1\n~~~~~\n\n* old accessors temporarily restored for backward compatibility (undocumented\n and to be removed in 1.0)\n\n* minor documentation fixes\n\n0.8.0\n~~~~~\n\n* code separated from ``lck.django``\n\n* PEP8-fied the accessor APIs\n\nAuthors\n-------\n\nGlued together by `\u0141ukasz Langa `_. Python 2.6 support\nby `Carl van Tonder `_.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ambv/dj.choices/", "keywords": "django dj extra contrib choices enum enumeration", "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "dj.choices", "package_url": "https://pypi.org/project/dj.choices/", "platform": "any", "project_url": "https://pypi.org/project/dj.choices/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/ambv/dj.choices/" }, "release_url": "https://pypi.org/project/dj.choices/0.11.0/", "requires_dist": null, "requires_python": null, "summary": "An enum implementation for Django forms and models.", "version": "0.11.0" }, "last_serial": 2419427, "releases": { "0.10.0": [ { "comment_text": "", "digests": { "md5": "9080b8f3aa01df2fe8153c432b1d754c", "sha256": "96d295872bd070d46cfd99c6db6b446898dbdec655fb3d866740899f3eee026f" }, "downloads": -1, "filename": "dj.choices-0.10.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9080b8f3aa01df2fe8153c432b1d754c", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 34037, "upload_time": "2014-10-16T22:02:15", "url": "https://files.pythonhosted.org/packages/d4/22/c89b3c5f7f71972b2f84c847aec51c1ed9e7516c8678ab4ead695b693384/dj.choices-0.10.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9bc23813c1250cb7e43c475070aed160", "sha256": "ed5547a0f635c3074ee607998a378465d70a84ce7ac1f9358f9be707adc636e9" }, "downloads": -1, "filename": "dj.choices-0.10.0.tar.gz", "has_sig": false, "md5_digest": "9bc23813c1250cb7e43c475070aed160", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28216, "upload_time": "2014-10-16T22:01:58", "url": "https://files.pythonhosted.org/packages/36/6f/67fb07f6c82cc7d61c843e411fbe9c4795d81f88d8c4e42c7ca524bab40e/dj.choices-0.10.0.tar.gz" } ], "0.11.0": [ { "comment_text": "", "digests": { "md5": "c80bbd76e9918e79846ff8025c2e0db4", "sha256": "2c23f03ead45d5710512c52988f105ffed4b0cabb8a2cdcbf45108153fe25517" }, "downloads": -1, "filename": "dj.choices-0.11.0.tar.gz", "has_sig": false, "md5_digest": "c80bbd76e9918e79846ff8025c2e0db4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28370, "upload_time": "2016-10-24T07:13:37", "url": "https://files.pythonhosted.org/packages/fe/cf/dd88a62c3bd0258b56476613831bbc040bf43b6d96fa5c91a0c4b556bb51/dj.choices-0.11.0.tar.gz" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "177535df65c1665392b57496d5f70203", "sha256": "a837eac034f44973bf5612b25c7b15a623a7d86eaa4bc750136af7ab1ed5529c" }, "downloads": -1, "filename": "dj.choices-0.8.0.tar.gz", "has_sig": false, "md5_digest": "177535df65c1665392b57496d5f70203", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17660, "upload_time": "2012-03-12T03:46:51", "url": "https://files.pythonhosted.org/packages/89/e2/2aa9dcff6e33c27f8d26b384481b58b6a008d9eacb22191fc5adf9032cf3/dj.choices-0.8.0.tar.gz" } ], "0.8.1": [ { "comment_text": "", "digests": { "md5": "b5937a16f2176d668adc90106d377b08", "sha256": "25f6c728bbe7093b8171a6477d9b7c580801b37bc263465b0c2697922bf895d5" }, "downloads": -1, "filename": "dj.choices-0.8.1.tar.gz", "has_sig": false, "md5_digest": "b5937a16f2176d668adc90106d377b08", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18047, "upload_time": "2012-03-12T23:27:35", "url": "https://files.pythonhosted.org/packages/55/39/46ecf20e99e4f60e5ed7e913911be0e37827a46b8bb359f3fdef78572090/dj.choices-0.8.1.tar.gz" } ], "0.8.2": [ { "comment_text": "", "digests": { "md5": "1007071466363abc3cd7edd58fd8b985", "sha256": "1b39b684651e22deda0832f6b0354333da396352087367c6c5b1bbe3e8b0ccfa" }, "downloads": -1, "filename": "dj.choices-0.8.2.tar.gz", "has_sig": false, "md5_digest": "1007071466363abc3cd7edd58fd8b985", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24353, "upload_time": "2012-03-13T06:54:23", "url": "https://files.pythonhosted.org/packages/fb/8e/63353fb80912ec6db1dba0108e9bc6170329d00ef8cc13ba14bc42130292/dj.choices-0.8.2.tar.gz" } ], "0.8.3": [ { "comment_text": "", "digests": { "md5": "84eb4dc8a987005e2b0a0b92e81fb84a", "sha256": "84f72b91f2ec751dadce95ab0f63af9f726d9ad56b9da97dac604f2ee1ad6c49" }, "downloads": -1, "filename": "dj.choices-0.8.3.tar.gz", "has_sig": false, "md5_digest": "84eb4dc8a987005e2b0a0b92e81fb84a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25508, "upload_time": "2012-03-19T12:11:53", "url": "https://files.pythonhosted.org/packages/20/04/c15d813d49bce42d84770774644cc4df853d805c6fc6d696f997f043aeb6/dj.choices-0.8.3.tar.gz" } ], "0.8.4": [ { "comment_text": "", "digests": { "md5": "f86d7306fdb23c6e6f1da5fccd67dd4a", "sha256": "95be01e4a11ab9345314439ad48a2772f25918f9537b56b3958d944673b9c62a" }, "downloads": -1, "filename": "dj.choices-0.8.4.tar.gz", "has_sig": false, "md5_digest": "f86d7306fdb23c6e6f1da5fccd67dd4a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25711, "upload_time": "2012-05-08T14:49:41", "url": "https://files.pythonhosted.org/packages/33/cf/50bd894f166aaadfdcd0550616739ba9b9bcfae651ceec403b13d0b85adc/dj.choices-0.8.4.tar.gz" } ], "0.8.5": [ { "comment_text": "", "digests": { "md5": "af4037708d8b1bd29ad35cfc10451371", "sha256": "8356b950ccf9c434fea54930d2c192955fa158372b0bf077000260a3228ec1b2" }, "downloads": -1, "filename": "dj.choices-0.8.5.tar.gz", "has_sig": false, "md5_digest": "af4037708d8b1bd29ad35cfc10451371", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26162, "upload_time": "2012-06-07T16:38:27", "url": "https://files.pythonhosted.org/packages/41/88/fce1b5cf127146a5ac5502e2a5fb6efe802c6ea6bcb37a54915050005ec6/dj.choices-0.8.5.tar.gz" } ], "0.8.6": [ { "comment_text": "", "digests": { "md5": "1f49ca8b6da81b3c56a84b5b4692a0f2", "sha256": "3e664e28cfada79917ecd6cac32637a458149a0fd911c4439ecc59d684ab36cc" }, "downloads": -1, "filename": "dj.choices-0.8.6.tar.gz", "has_sig": false, "md5_digest": "1f49ca8b6da81b3c56a84b5b4692a0f2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27101, "upload_time": "2012-06-18T13:41:45", "url": "https://files.pythonhosted.org/packages/32/78/ccdfb2441731629b951395a34f1c2423244bd0f32a84205bd6603e4fe516/dj.choices-0.8.6.tar.gz" } ], "0.9.0": [ { "comment_text": "", "digests": { "md5": "6329ee272a28cfb1643fec8b34e00c8b", "sha256": "38bb01e079d0c6762e4ac1add2779c90f06a7197803a3f62a6b8b7dcf1b9e002" }, "downloads": -1, "filename": "dj.choices-0.9.0.tar.gz", "has_sig": false, "md5_digest": "6329ee272a28cfb1643fec8b34e00c8b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27630, "upload_time": "2012-08-30T22:55:13", "url": "https://files.pythonhosted.org/packages/10/95/2a506204e87a5619338810bd223ee9ba153905c55fb275a6dd602bd82798/dj.choices-0.9.0.tar.gz" } ], "0.9.1": [ { "comment_text": "", "digests": { "md5": "ee96d38df9c689a3e731ea52e851fc80", "sha256": "886316befc7c104ffa788c3589b503cd7d69b836d67100fd373ab60f770f08e7" }, "downloads": -1, "filename": "dj.choices-0.9.1.tar.gz", "has_sig": false, "md5_digest": "ee96d38df9c689a3e731ea52e851fc80", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27459, "upload_time": "2013-03-05T00:06:02", "url": "https://files.pythonhosted.org/packages/7f/fd/cd8ca2c1a8a58d991641f3e25376f4501ec32da50962143c1b0d5669dc1e/dj.choices-0.9.1.tar.gz" } ], "0.9.2": [ { "comment_text": "", "digests": { "md5": "873737cfcad6e34837760ca9be3d308b", "sha256": "17a6012b924eeb39c7fcc303392caa93c541e1107affba3aeeb2ac64e160b5e0" }, "downloads": -1, "filename": "dj.choices-0.9.2.tar.gz", "has_sig": false, "md5_digest": "873737cfcad6e34837760ca9be3d308b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27801, "upload_time": "2013-03-06T22:17:42", "url": "https://files.pythonhosted.org/packages/a0/7e/4728f15322676f66ecd23e8811670e6f59f17c80618388b28c2660f4bb77/dj.choices-0.9.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c80bbd76e9918e79846ff8025c2e0db4", "sha256": "2c23f03ead45d5710512c52988f105ffed4b0cabb8a2cdcbf45108153fe25517" }, "downloads": -1, "filename": "dj.choices-0.11.0.tar.gz", "has_sig": false, "md5_digest": "c80bbd76e9918e79846ff8025c2e0db4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28370, "upload_time": "2016-10-24T07:13:37", "url": "https://files.pythonhosted.org/packages/fe/cf/dd88a62c3bd0258b56476613831bbc040bf43b6d96fa5c91a0c4b556bb51/dj.choices-0.11.0.tar.gz" } ] }