Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
django-admin-lightweight-date-hierarchy
Advanced tools
.. image:: https://badge.fury.io/py/django-admin-lightweight-date-hierarchy.svg :target: https://badge.fury.io/py/django-admin-lightweight-date-hierarchy
.. image:: https://github.com/hakib/django-admin-lightweight-date-hierarchy/actions/workflows/main.yml/badge.svg?branch=master :target: https://github.com/hakib/django-admin-lightweight-date-hierarchy/actions/workflows/main.yml?query=branch%3Amaster
.. image:: https://codecov.io/gh/hakib/django-admin-lightweight-date-hierarchy/branch/master/graph/badge.svg :target: https://codecov.io/gh/hakib/django-admin-lightweight-date-hierarchy
NOTE: Some of the functionality provided by this extension is included as part of Django <https://github.com/django/django/pull/9469>
_ starting at
version 2.1.
The built-in date_hierarchy
_ tag performs a query to find the dates for which there is data.
On large tables this query can be very expensive.
To prevent additional queries, set date_hierarchy_drilldown = False
on the ModelAdmin
.
When drill-down is disabled the tag will generate a default range of dates based solely
on the selected hierarchy level - without performing a query.
Default options for hierarchy levels:
When date_hierarchy_drilldown = True
or when not set the default behaviour is preserved.
.. _date_hierarchy
: https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.ModelAdmin.date_hierarchy
Python>=3.7
Django 3.2, 4.2, >=5
Install django-admin-lightweight-date-hierarchy::
pip install django-admin-lightweight-date-hierarchy
Add it to your INSTALLED_APPS
:
.. code-block:: python
INSTALLED_APPS = (
...
'django_admin_lightweight_date_hierarchy',
...
)
Add the following to any ModelAdmin
with date_hierarchy
to prevent the default drill-down behaviour:
.. code-block:: python
@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
date_hierarchy = 'created'
date_hierarchy_drilldown = False
To change the default dates generated by the template tag for any level in the hierarchy, implement a
function called get_date_hierarchy_drilldown(self, year_lookup=None, month_lookup=None)
on the ModelAdmin
.
The function receives the date hierarchy filter and is expected to return a list of dates to offer for drill-down.
For example, a custom drill-down that offers only past dates:
.. code-block:: python
import datetime
import calendar
from django.utils import timezone
from django.contrib import admin
@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
date_hierarchy = 'created'
date_hierarchy_drilldown = False
def get_date_hierarchy_drilldown(self, year_lookup, month_lookup):
"""Drill-down only on past dates."""
today = timezone.now().date()
if year_lookup is None and month_lookup is None:
# Past 3 years.
return (
datetime.date(y, 1, 1)
for y in range(today.year - 2, today.year + 1)
)
elif year_lookup is not None and month_lookup is None:
# Past months of selected year.
this_month = today.replace(day=1)
return (
month for month in (
datetime.date(int(year_lookup), month, 1)
for month in range(1, 13)
) if month <= this_month
)
elif year_lookup is not None and month_lookup is not None:
# Past days of selected month.
days_in_month = calendar.monthrange(year_lookup, month_lookup)[1]
return (
day for day in (
datetime.date(year_lookup, month_lookup, i + 1)
for i in range(days_in_month)
) if day <= today
)
More about the process of developing date hierarchy drill-down in this blog post scaling django admin date hierarchy
_.
.. _scaling django admin date hierarchy
: https://hakibenita.com/scaling-django-admin-date-hierarchy
Django filters the queryset for a given level in the date hierarchy using a database
function to extract the relevent date part. For example, when filtering a queryset on
a created
date field for November 2017, Django will execute the following query:
.. code-block:: sql
SELECT
...
FROM
app_model
WHERE
created BETWEEN '2017-01-01 00:00:00' AND '2017-12-31 23:59:59.999999'
AND EXTRACT('month', created) = 11
A function is opaque to the database optimizer. If you have a range-based (btree) index on the field, using EXTRACT does not limit the range at all, and so the index is not utilized properly which might lead to a sub optimal execution plan.
There are several approaches to tackle this issue. For example, in databases that support function based indexes the developer can add an index on the specific function to try and improve the performace of the query. The downside to this approach is having to maintain additional indexes for each level of the hierarchy. Additional indexes slow down insert and update operations, and take up space.
Another approach is to simplify the condition used by Django to filter the queryset for any given level in the hierarchy:
.. code-block:: sql
SELECT
...
FROM
app_model
WHERE
created >= '2017-11-01 00:00:00'
AND created < '2017-12-01 00:00:00'
This is what RangeBasedDateHierarchyListFilter
does.
To achieve the above query, add the following to your ModelAdmin:
.. code-block:: python
from django.contrib import admin
from django_admin_lightweight_date_hierarchy.admin import RangeBasedDateHierarchyListFilter
@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
date_hierarchy = 'created'
list_filter = (
RangeBasedDateHierarchyListFilter,
)
More about the motivation and the performace of RangeBasedDateHierarchyListFilter
in this blog post Django Admin Range-Based Date Hierarchy
_.
.. _Django Admin Range-Based Date Hierarchy
: https://codeburst.io/django-admin-range-based-date-hierarchy-37955b12ea4e
::
source <YOURVIRTUALENV>/bin/activate
(venv) $ pip install tox
(venv) $ tox
FAQs
Use Django Admin date hierarchy queries freely!
We found that django-admin-lightweight-date-hierarchy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.