{ "info": { "author": "Vlad Starostin", "author_email": "drtyrsa@yandex.ru", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "=========================\nDjango Cached Modelforms\n=========================\n\nThe application provides ``ModelForm``, ``ModelChoiceField``, ``ModelMultipleChoiceField`` implementations that can accept lists of objects, not just querysets. This can prevent these fields from hitting DB every time they are created.\n\nThe problem\n=========================\n\nImagine the following form::\n\n class MyForm(forms.Form):\n obj = ModelChoiceField(queryset=MyModel.objects.all())\n\nEvery time you render the form ``ModelChoiceField`` field will hit DB. What if you don't want it? Can't you just pass the list of objects (from cache) to the field? You can't. What to do? Use CachedModelChoiceField.\n\nThe solution\n=========================\n\nForm with ``CachedModelChoiceField``::\n\n from cached_modelforms import CachedModelChoiceField\n\n class MyForm(forms.Form):\n obj = CachedModelChoiceField(objects=lambda:[obj1, obj2, obj3])\n\nThis field will act like regular ``ModelChoiceField``, but you pass a callable that returns the list of objects, not queryset, to it. Calable is needed because we don't want to evaluate the list out only once.\n\nA callable can return:\n\n* a list of objects: ``[obj1, obj2, obj3, ...]``. ``obj`` should have ``pk`` property and be coercible to unicode.\n* a list of tuples: ``[(pk1, obj1), (pk2, obj2), (pk3, obj3), ...]``.\n* a dict: ``{pk1: obj1, pk2: obj2, pk3: obj3, ...}``. Note that ``dict`` is unsorted so the items will be ordered by ``pk`` lexicographically.\n\nSame is for ``CachedModelMultipleChoiceField``.\n\nWarnings\n=========================\nThere is no special validation here. The field won't check that the object is an instance of a particular model, it won't even check that object is a model instance. And it's up to you to keep cache relevant. Usually it's not a problem.\n\nModelform\n=========================\nBut what about modelforms? They still use original ``ModelChoiceField`` for ``ForeignKey`` fields. This app has its own ``ModelForm`` that uses ``CachedModelChoiceField`` and ``CachedModelMultipleChoiceField``. The usage is following::\n\n # models.py\n class Category(models.Model):\n title = CharField(max_length=64)\n\n class Tag(models.Model):\n title = CharField(max_length=64)\n\n class Product(models.Model):\n title = CharField(max_length=64)\n category = models.ForeignKey(Category)\n tags = models.ManyToManyField(Tag)\n\n\n # forms.py\n class ProductForm(cached_modelforms.ModelForm):\n class Meta:\n model = Product\n objects = {\n 'category': lambda:[...], # your callable here\n 'tags': lambda:[...], # and here\n }\n\nThat's all. If you don't specify ``objects`` for some field, regular ``Model[Multiple]ChoiceField`` will be used.\n\nm2m_initials\n=========================\nIf you use ``ManyToManyField`` in ``ModelForm`` and load an ``instance`` to it, it will make one extra DB request (JOINed!) \u2013 to get initials for this field. Can we cache it too? Yes. You need a function that accepts model instance and returns a list of ``pk``'s \u2013 initials for the field. Here's a modification of previous example::\n\n # models.py\n\n class Product(models.Model):\n title = CharField(max_length=64)\n category = models.ForeignKey(Category)\n tags = models.ManyToManyField(Tag)\n\n def tags_cached(self):\n cache_key = 'tags_for_%(product_pk)d' % {'product_pk': self.pk}\n cached = cache.get(cache_key)\n if cached is not None:\n return cached\n result = list(self.tags.all())\n cache.set(cache_key, result)\n return result\n\n # forms.py\n\n class ProductForm(cached_modelforms.ModelForm):\n class Meta:\n model = Product\n objects = {\n 'category': lambda:[...], # your callable here\n 'tags': lambda:[...], # and here\n }\n m2m_initials = {'tags': lambda instance: [x.pk for x in instance.tags_cached()]}\n\nCompatibility\n=========================\nFor sure is works fine with Django 1.2-1.4. Altering ``ModelForm`` has required some copy-pasting from Django source code. It couldn't be done with inheritance. I don't think there will be problems with futher versions of Django, but don't forget to run the tests if something seems wrong.\n", "description_content_type": "", "docs_url": null, "download_url": "https://github.com/drtyrsa/django-cached-modelforms/zipball/master", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/drtyrsa/django-cached-modelforms", "keywords": "", "license": "BSD License", "maintainer": "", "maintainer_email": "", "name": "django-cached-modelforms", "package_url": "https://pypi.org/project/django-cached-modelforms/", "platform": "", "project_url": "https://pypi.org/project/django-cached-modelforms/", "project_urls": { "Download": "https://github.com/drtyrsa/django-cached-modelforms/zipball/master", "Homepage": "https://github.com/drtyrsa/django-cached-modelforms" }, "release_url": "https://pypi.org/project/django-cached-modelforms/0.2.3/", "requires_dist": null, "requires_python": "", "summary": "ModelChoiceField implementation that can accept lists of objects, not just querysets", "version": "0.2.3" }, "last_serial": 5002142, "releases": { "0.2.1": [ { "comment_text": "", "digests": { "md5": "3ff6af62ea4129dff5834171a80e157b", "sha256": "7f17e74e58021c61013899d92f7b79c94e6fa91bfd30cdf83d7da733cdc11091" }, "downloads": -1, "filename": "django-cached-modelforms-0.2.1.tar.gz", "has_sig": false, "md5_digest": "3ff6af62ea4129dff5834171a80e157b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9227, "upload_time": "2013-11-02T05:54:53", "url": "https://files.pythonhosted.org/packages/c1/f0/01d5fe5ef263a09a9184f1c633972fcaf6ac1ee5b80426fe69b48e223699/django-cached-modelforms-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "62c3bd42740bf151576fa01195993b4a", "sha256": "76ad8dd79dedcff7cb984988348073267eaebf177b14807422034b5ee2300aa9" }, "downloads": -1, "filename": "django-cached-modelforms-0.2.2.tar.gz", "has_sig": true, "md5_digest": "62c3bd42740bf151576fa01195993b4a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7518, "upload_time": "2016-03-16T10:56:13", "url": "https://files.pythonhosted.org/packages/f9/d2/d11dcc57a7c4d6c139deb0d7df61cf2aeb48d7cd05c3b002bf911edeb571/django-cached-modelforms-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "3ec6fd2c316d21c7118debcd0726d53d", "sha256": "b46d15e91b592c0fd29638f5420a39242acaffb964d7ed4d6a6d0debaf4fb695" }, "downloads": -1, "filename": "django_cached_modelforms-0.2.3-py3-none-any.whl", "has_sig": true, "md5_digest": "3ec6fd2c316d21c7118debcd0726d53d", "packagetype": "bdist_wheel", "python_version": "3.7", "requires_python": null, "size": 8808, "upload_time": "2019-03-29T08:42:57", "url": "https://files.pythonhosted.org/packages/f7/c7/a99093dfa8e3d87ae829014059c97554b80461cbcde0b7d10a953601f0af/django_cached_modelforms-0.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "92c4791810aca77d34c8d1e202686b69", "sha256": "c742227dc4fafd9fd2a75a946dfdfe38a3348504f62791fe96db52bb24e271d3" }, "downloads": -1, "filename": "django-cached-modelforms-0.2.3.tar.gz", "has_sig": true, "md5_digest": "92c4791810aca77d34c8d1e202686b69", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7951, "upload_time": "2019-03-29T08:42:53", "url": "https://files.pythonhosted.org/packages/88/b7/f434cff4b7439316f1ec7ddb64d1c44da1a6e7db5e84033faede5c4aafcc/django-cached-modelforms-0.2.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3ec6fd2c316d21c7118debcd0726d53d", "sha256": "b46d15e91b592c0fd29638f5420a39242acaffb964d7ed4d6a6d0debaf4fb695" }, "downloads": -1, "filename": "django_cached_modelforms-0.2.3-py3-none-any.whl", "has_sig": true, "md5_digest": "3ec6fd2c316d21c7118debcd0726d53d", "packagetype": "bdist_wheel", "python_version": "3.7", "requires_python": null, "size": 8808, "upload_time": "2019-03-29T08:42:57", "url": "https://files.pythonhosted.org/packages/f7/c7/a99093dfa8e3d87ae829014059c97554b80461cbcde0b7d10a953601f0af/django_cached_modelforms-0.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "92c4791810aca77d34c8d1e202686b69", "sha256": "c742227dc4fafd9fd2a75a946dfdfe38a3348504f62791fe96db52bb24e271d3" }, "downloads": -1, "filename": "django-cached-modelforms-0.2.3.tar.gz", "has_sig": true, "md5_digest": "92c4791810aca77d34c8d1e202686b69", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7951, "upload_time": "2019-03-29T08:42:53", "url": "https://files.pythonhosted.org/packages/88/b7/f434cff4b7439316f1ec7ddb64d1c44da1a6e7db5e84033faede5c4aafcc/django-cached-modelforms-0.2.3.tar.gz" } ] }