{ "info": { "author": "Daniel Naab", "author_email": "dan@crushingpennies.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Framework :: Django", "Framework :: Django :: 1.10", "Framework :: Django :: 1.9", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3" ], "description": "# django-roesti\n\n`django-roesti` provides a `HashedModel`, a Django model whose primary key is a\nhash of its contents. This enables efficient use of the database when you need to reference data by its identity while minimizing round trips to\nthe database, or encounter the same data often, and need to ensure that it\nexists in your database without duplicating it.\n\nHashes are generated by converting values into Python immutable types and then\ngenerating the md5 hash of its pickled value.\n\n`HashedModels` that maintain references to other `HashedModels` are supported.\n\n`django-roesti` has been tested with Python 3.6 and Django 1.9.\n\nPull requests welcome.\n\n## Roesti?\n\nA *R\u00f6sti* is a Swiss potato pancake, similar to hash browns. Get it?\n\n## Installation\n\nInstall from PyPI:\n\n```bash\npip install django-roesti\n```\n\n... and add to your `INSTALLED_APPS`:\n\n```python\nINSTALLED_APPS = [\n # ...\n 'roesti',\n]\n```\n\n## Usage Examples\n\nHashes are calculated from the fields specified in `hash_fields`. Foreign keys\nshould be hashed on the ID value.\n\nFor example, given these models:\n\n```python\nfrom roesti.models import HashedModel\n\n\nclass TestModel(HashedModel):\n hash_fields = ['char_field_1', 'integer_field_1']\n\n char_field_1 = models.CharField(max_length=32)\n integer_field_1 = models.IntegerField()\n\n\nclass TestReferencesModel(HashedModel):\n hash_fields = ['test_model_1_id', 'test_model_2_id', 'integer_field_1']\n\n test_model_1 = models.ForeignKey(TestModel)\n test_model_2 = models.ForeignKey(TestModel)\n integer_field_1 = models.IntegerField()\n```\n\nYou may create new or retrieve existing model instances with the `ensure`\nfunction. `ensure` accepts either dictionaries or model instances.\n\n```python\nmy_models = TestModel.objects.ensure([{\n 'char_field_1': 'field 1 value 1',\n 'integer_field_1': 1\n}, {\n 'char_field_1': 'field 1 value 2',\n 'integer_field_1': 2\n}, {\n 'char_field_1': 'field 1 value 3',\n 'integer_field_1': 3\n}])\n\nmy_reference_models = TestReferencesModel.objects.ensure({\n 'test_model_1': {\n 'char_field_1': 'field 1 value 1',\n 'integer_field_1': 1\n },\n 'test_model_2': {\n 'char_field_2': 'field 1 value 2',\n 'integer_field_1': 2\n },\n 'integer_field_1': 3\n})\n```\n\nReverse relationships may be used to calculate the item's hash, and passed to\nthe `ensure` method. For instance, this implements an ordered list of items.\nNote the use of `items` in `hash_fields` for `TestOrderedList`:\n\n```python\nclass TestOrderedList(HashedModel):\n hash_fields = ('name', 'items')\n name = models.TextField()\n\n\nclass TestItemDetails(HashedModel):\n hash_fields = ('text',)\n text = models.TextField()\n\n\nclass TestOrderedListItem(HashedModel):\n hash_fields = ('lst_id', 'order', 'details',)\n lst = models.ForeignKey(TestOrderedList, related_name='items')\n order = models.IntegerField()\n details = models.ForeignKey(TestItemDetails)\n\n instances = TestOrderedList.objects.ensure([{\n 'name': 'My list 1',\n 'items': [{\n 'order': index,\n 'details': {\n 'text': '1 Item %d' % index\n }\n } for index in range(10)]\n }, {\n 'name': 'My list 2',\n 'items': [{\n 'order': index,\n 'details': {\n 'text': '2 Item %d' % index\n }\n } for index in range(10)]\n }, {\n 'name': 'My list 3',\n 'items': [{\n 'order': index,\n 'details': {\n 'text': '3 Item %d' % index\n }\n } for index in range(10)]\n }])\n```\n\nThere is also a `HashedList` model for managing ordered lists of hashed items.\nTo use, create the corresponding `HashedModel` and a mapping table. Note that\nif you need to store references to the list in a `HasedModel`, as in the above\nexample, you should not used `HashedList`.\n\n```python\nclass TestItem(HashedModel):\n hash_fields = ('text',)\n text = models.TextField(blank=True, null=True)\n\n\nclass TestListItem(HashedListItemModel):\n item = models.ForeignKey(TestItem)\n\n\nitems = [\n TestItem(text='Item %d' % index)\n for index in range(10)\n]\nmy_list = HashedList.objects.ensure_list(TestItem, items)\n```", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/danielnaab/django-roesti", "keywords": "django", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "django-roesti", "package_url": "https://pypi.org/project/django-roesti/", "platform": "", "project_url": "https://pypi.org/project/django-roesti/", "project_urls": { "Homepage": "https://github.com/danielnaab/django-roesti" }, "release_url": "https://pypi.org/project/django-roesti/0.1.1/", "requires_dist": null, "requires_python": "", "summary": "Provides a Django model keyed on the hash of its contents.", "version": "0.1.1" }, "last_serial": 2802368, "releases": { "0.0.2": [ { "comment_text": "", "digests": { "md5": "23e68ffa9cae0003731a8aeca6ec80cb", "sha256": "51341e7ef7cb3f81ea81bfe28b756a20b3521a82b9057a2341d045ad80d8c70c" }, "downloads": -1, "filename": "django-roesti-0.0.2.tar.gz", "has_sig": false, "md5_digest": "23e68ffa9cae0003731a8aeca6ec80cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7065, "upload_time": "2017-04-05T19:59:36", "url": "https://files.pythonhosted.org/packages/7f/08/3729143dfaa9cb9116867ddaf11d7d96c975459db665061862663b9d6bf7/django-roesti-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "71bac545dd6a6b25b0c9de71e5fb6b34", "sha256": "167a534724423b964dd84ca67a32a9a89c1be7ed6656696d51ae7174897399c9" }, "downloads": -1, "filename": "django-roesti-0.0.3.tar.gz", "has_sig": false, "md5_digest": "71bac545dd6a6b25b0c9de71e5fb6b34", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7156, "upload_time": "2017-04-05T21:08:37", "url": "https://files.pythonhosted.org/packages/a1/e0/75fa58b31d921c76a5e9db92eddad8fbb8f4b4ac29bc6058989fd2f59a3f/django-roesti-0.0.3.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "27b10b7807dac823e4d67dc20b059b5f", "sha256": "dc88d6d5b5b38d998281b3d03fb8d638f48e111e5230011ddaed4b5d85971ab6" }, "downloads": -1, "filename": "django-roesti-0.1.0.tar.gz", "has_sig": false, "md5_digest": "27b10b7807dac823e4d67dc20b059b5f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7239, "upload_time": "2017-04-07T21:23:33", "url": "https://files.pythonhosted.org/packages/65/d9/9595ea4850c3ac3d527d03a5573974a20e4ae22cf347bc20de0993f92846/django-roesti-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "d819b8d5c9408580eb0cf44012db2ee9", "sha256": "39f091aacc3fc382e533c0a7aa49a899fb916643592b97b890d77a161f1d76c6" }, "downloads": -1, "filename": "django-roesti-0.1.1.tar.gz", "has_sig": false, "md5_digest": "d819b8d5c9408580eb0cf44012db2ee9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7683, "upload_time": "2017-04-13T21:09:21", "url": "https://files.pythonhosted.org/packages/86/4c/6b28a18895a959ee6ca660d64f7295cb59dca111ae8fd4915e1edd9a892c/django-roesti-0.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d819b8d5c9408580eb0cf44012db2ee9", "sha256": "39f091aacc3fc382e533c0a7aa49a899fb916643592b97b890d77a161f1d76c6" }, "downloads": -1, "filename": "django-roesti-0.1.1.tar.gz", "has_sig": false, "md5_digest": "d819b8d5c9408580eb0cf44012db2ee9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7683, "upload_time": "2017-04-13T21:09:21", "url": "https://files.pythonhosted.org/packages/86/4c/6b28a18895a959ee6ca660d64f7295cb59dca111ae8fd4915e1edd9a892c/django-roesti-0.1.1.tar.gz" } ] }