{ "info": { "author": "Haki Benita", "author_email": "hakibenita@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Framework :: Django", "Framework :: Django :: 1.10", "Framework :: Django :: 1.11", "Framework :: Django :: 1.9", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "=============================\nDjango Admin lightweight date hierarchy\n=============================\n\n.. image:: https://badge.fury.io/py/django-admin-lightweight-date-hierarchy.svg\n :target: https://badge.fury.io/py/django-admin-lightweight-date-hierarchy\n\n.. image:: https://travis-ci.org/hakib/django-admin-lightweight-date-hierarchy.svg?branch=master\n :target: https://travis-ci.org/hakib/django-admin-lightweight-date-hierarchy\n\n.. image:: https://codecov.io/gh/hakib/django-admin-lightweight-date-hierarchy/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/hakib/django-admin-lightweight-date-hierarchy\n\n\nDjango Admin date_hierarchy with zero queries\n----------------------------------------------\n\nThe built-in `date_hierarchy`_ tag performs a query to find the dates for which there is data.\nOn large tables this query can be very expensive.\n\nTo prevent additional queries, set ``date_hierarchy_drilldown = False`` on the ``ModelAdmin``.\nWhen drill-down is disabled the tag will generate a default range of dates based solely\non the selected hierarchy level - without performing a query.\n\nDefault options for hierarchy levels:\n\n- None - +-3 years from current year.\n- Year - all months of the selected year.\n- Month - all days of the selected month.\n\nWhen ``date_hierarchy_drilldown = True`` or when not set the default behaviour is preserved.\n\n.. _`date_hierarchy`: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.ModelAdmin.date_hierarchy\n\n\nSupport\n----------\n\nPython 2.7, 3.4, 3.5, 3.6\n\nDjango 1.9, 1.10, 1.11\n\n\nQuickstart\n----------\n\nInstall django-admin-lightweight-date-hierarchy::\n\n pip install django-admin-lightweight-date-hierarchy\n\nAdd it to your `INSTALLED_APPS`:\n\n.. code-block:: python\n\n INSTALLED_APPS = (\n ...\n 'django_admin_lightweight_date_hierarchy',\n ...\n )\n\nAdd the following to any ``ModelAdmin`` with ``date_hierarchy`` to prevent the default drill-down behaviour:\n\n.. code-block:: python\n\n @admin.register(MyModel)\n class MyModelAdmin(admin.ModelAdmin):\n date_hierarchy = 'created'\n date_hierarchy_drilldown = False\n\n\nTo change the default dates generated by the template tag for any level in the hierarchy, implement a\nfunction called ``get_date_hierarchy_drilldown(self, year_lookup=None, month_lookup=None)`` on the ``ModelAdmin``.\nThe function receives the date hierarchy filter and is expected to return a list of dates to offer for drill-down.\n\nFor example, a custom drill-down that offers only past dates:\n\n\n.. code-block:: python\n\n\n import datetime\n import calendar\n\n from django.utils import timezone\n from django.contrib import admin\n\n\n @admin.register(MyModel)\n class MyModelAdmin(admin.ModelAdmin):\n date_hierarchy = 'created'\n date_hierarchy_drilldown = False\n\n def get_date_hierarchy_drilldown(self, year_lookup, month_lookup):\n \"\"\"Drill-down only on past dates.\"\"\"\n\n today = timezone.now().date()\n\n if year_lookup is None and month_lookup is None:\n # Past 3 years.\n return (\n datetime.date(y, 1, 1)\n for y in range(today.year - 2, today.year + 1)\n )\n\n elif year_lookup is not None and month_lookup is None:\n # Past months of selected year.\n this_month = today.replace(day=1)\n return (\n month for month in (\n datetime.date(int(year_lookup), month, 1)\n for month in range(1, 13)\n ) if month <= this_month\n )\n\n elif year_lookup is not None and month_lookup is not None:\n # Past days of selected month.\n days_in_month = calendar.monthrange(year_lookup, month_lookup)[1]\n return (\n day for day in (\n datetime.date(year_lookup, month_lookup, i + 1)\n for i in range(days_in_month)\n ) if day <= today\n )\n\n\nRangeBasedDateHierarchyListFilter\n----------------------------------------------\n\nDjango filters the queryset for a given level in the date hierarchy using a database\nfunction to extract the relevent date part. For example, when filtering a queryset on\na `created` date field for November 2017, Django will execute the following query:\n\n.. code-block:: sql\n\n SELECT\n ...\n FROM\n app_model\n WHERE\n created BETWEEN '2017-01-01 00:00:00' AND '2017-12-31 23:59:59.999999'\n AND EXTRACT('month', created) = 11\n\nA function is opaque to the database optimizer. If you have a range-based (btree) index\non the field, using EXTRACT does not limit the range at all, and so the index is not\nutilized properly which might lead to a sub optimal execution plan.\n\nThere are several approaches to tackle this issue. For exmaple, in databases that support\nfunction based indexes the developer can add an index on the specific function to try and\nimprove the performace of the query. The downside to this approach is having to maintain\nadditional indexes for each level of the hierarchy. Additional indexes slow down insert\nand update operations, and take up space.\n\nAnother approach is to simplify the condition used by Django to filter the queryset\nfor any given level in the hierarchy:\n\n.. code-block:: sql\n\n SELECT\n ...\n FROM\n app_model\n WHERE\n created >= '2017-11-01 00:00:00'\n AND created < '2017-12-01 00:00:00'\n\n\nThis is what RangeBasedDateHierarchyListFilter does.\n\nTo achieve the above query, simply add the following to your ModelAdmin:\n\n.. code-block:: python\n\n\n from django.contrib import admin\n from django_admin_lightweight_date_hierarchy.admin import RangeBasedDateHierarchyListFilter\n\n\n @admin.register(MyModel)\n class MyModelAdmin(admin.ModelAdmin):\n date_hierarchy = 'created'\n\n list_filters = (\n RangeBasedDateHierarchyListFilter,\n )\n\n\nBlog Post\n----------\n\nYou can read more about this package in my blog post `scaling django admin date hierarchy`_.\n\n.. _`scaling django admin date hierarchy`: https://medium.com/@hakibenita/scaling-django-admin-date-hierarchy-85c8e441dd4c\n\n\nRunning Tests\n-------------\n\n::\n\n source /bin/activate\n (venv) $ pip install tox\n (venv) $ tox\n\n\nCredits\n-------\n\nTools used in rendering this package:\n\n* Cookiecutter_\n* `cookiecutter-djangopackage`_\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`cookiecutter-djangopackage`: https://github.com/pydanny/cookiecutter-djangopackage\n\n\n\n\nHistory\n-------\n\n0.3.0 (2017-11-24)\n++++++++++++++++++\n\n* Added RangeBasedDateHierarchyListFilter.\n\n0.2.0 (2017-10-21)\n++++++++++++++++++\n\n* Option to provide custom drill down for any level in the hierarchy.\n\n\n0.1.0 (2017-09-21)\n++++++++++++++++++\n\n* First release on PyPI.\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/hakib/django-admin-lightweight-date-hierarchy", "keywords": "django-admin-lightweight-date-hierarchy", "license": "MIT, Django", "maintainer": "", "maintainer_email": "", "name": "django-admin-lightweight-date-hierarchy", "package_url": "https://pypi.org/project/django-admin-lightweight-date-hierarchy/", "platform": "", "project_url": "https://pypi.org/project/django-admin-lightweight-date-hierarchy/", "project_urls": { "Homepage": "https://github.com/hakib/django-admin-lightweight-date-hierarchy" }, "release_url": "https://pypi.org/project/django-admin-lightweight-date-hierarchy/0.3.0/", "requires_dist": null, "requires_python": "", "summary": "Using django admin date hierarchy queries free!", "version": "0.3.0" }, "last_serial": 3360708, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "c75638a5913d4b66cd45891e23f1e26b", "sha256": "3334bb706cc5f4beb2290e1eac38465ab9f1abf0d45f1841d3cd3a132633229c" }, "downloads": -1, "filename": "django_admin_lightweight_date_hierarchy-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "c75638a5913d4b66cd45891e23f1e26b", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 7751, "upload_time": "2017-09-27T16:48:12", "url": "https://files.pythonhosted.org/packages/5b/46/19af60ecdc0b1e07e1d08d753da28c76cc83077598c61d3548c208f32f91/django_admin_lightweight_date_hierarchy-0.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "62c359ca2bcd4739c3a255c1dbc99d5a", "sha256": "e1ef25ad4efd469adec6b303f35d753315c21b046dfcfa0ba15afdde177af797" }, "downloads": -1, "filename": "django-admin-lightweight-date-hierarchy-0.1.0.tar.gz", "has_sig": false, "md5_digest": "62c359ca2bcd4739c3a255c1dbc99d5a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7864, "upload_time": "2017-09-27T17:40:41", "url": "https://files.pythonhosted.org/packages/4a/64/6e77b525fa739c97232d1a499bf8130ee7ed0c85d727e9c958b23418ad1e/django-admin-lightweight-date-hierarchy-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "5846020d6c42bbca5ba0be289e6a36e4", "sha256": "225a7177757e025d524bbeff08996c1f179809075986b466cdd1db85e55f5cf7" }, "downloads": -1, "filename": "django-admin-lightweight-date-hierarchy-0.2.0.tar.gz", "has_sig": false, "md5_digest": "5846020d6c42bbca5ba0be289e6a36e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8808, "upload_time": "2017-10-21T13:36:22", "url": "https://files.pythonhosted.org/packages/c0/17/a13f632d8b05372a458409be34b4fcd21c0f09d426343eed756ab36a626c/django-admin-lightweight-date-hierarchy-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "5acb5016c230ac276549b6ca788d4cfd", "sha256": "d9146fc50fff81d68ddebaaacba9b168f3a02afc8d8314528998c181ce50d606" }, "downloads": -1, "filename": "django_admin_lightweight_date_hierarchy-0.3.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5acb5016c230ac276549b6ca788d4cfd", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 11741, "upload_time": "2017-11-24T12:03:55", "url": "https://files.pythonhosted.org/packages/c0/1c/0fb593e4a4ed6b49a1ebab94cea3328a472a2f21371f6047877ea5fce7cd/django_admin_lightweight_date_hierarchy-0.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1be608eef9cf6051c4a2b79d5f96325e", "sha256": "3e368154aa775162cdbcc5153574e69282f2542152364f88a38640dbbcafe52b" }, "downloads": -1, "filename": "django-admin-lightweight-date-hierarchy-0.3.0.tar.gz", "has_sig": false, "md5_digest": "1be608eef9cf6051c4a2b79d5f96325e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10452, "upload_time": "2017-11-24T12:03:52", "url": "https://files.pythonhosted.org/packages/7c/b1/ef97eedbbb2a35d3abdf122b510f2deeb3796484f40a821003379481423a/django-admin-lightweight-date-hierarchy-0.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5acb5016c230ac276549b6ca788d4cfd", "sha256": "d9146fc50fff81d68ddebaaacba9b168f3a02afc8d8314528998c181ce50d606" }, "downloads": -1, "filename": "django_admin_lightweight_date_hierarchy-0.3.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5acb5016c230ac276549b6ca788d4cfd", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 11741, "upload_time": "2017-11-24T12:03:55", "url": "https://files.pythonhosted.org/packages/c0/1c/0fb593e4a4ed6b49a1ebab94cea3328a472a2f21371f6047877ea5fce7cd/django_admin_lightweight_date_hierarchy-0.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1be608eef9cf6051c4a2b79d5f96325e", "sha256": "3e368154aa775162cdbcc5153574e69282f2542152364f88a38640dbbcafe52b" }, "downloads": -1, "filename": "django-admin-lightweight-date-hierarchy-0.3.0.tar.gz", "has_sig": false, "md5_digest": "1be608eef9cf6051c4a2b79d5f96325e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10452, "upload_time": "2017-11-24T12:03:52", "url": "https://files.pythonhosted.org/packages/7c/b1/ef97eedbbb2a35d3abdf122b510f2deeb3796484f40a821003379481423a/django-admin-lightweight-date-hierarchy-0.3.0.tar.gz" } ] }