- Installation
- Quick start
- Template filters
- Aggregation
- Model mixins
- Database functions
- HTTP Response
- WSGI Request
- Management
- Middleware
- Auth Backend
- Permissions
- Lockers
pip install django-extra-tools
Enable django-extra-tools
INSTALLED_APPS = [
…
'django_extra_tools',
]
Install SQL functions
python manage.py migrate
Parse datetime from string.
{% load parse %}
{{ string_datetime|parse_datetime|date:"Y-m-d H:i" }}
Parse date from string.
{% load parse %}
{{ string_date|parse_date|date:"Y-m-d" }}
Parse time from string.
{% load parse %}
{{ string_time|parse_time|date:"H:i" }}
Parse duration (timedelta) from string.
{% load parse %}
{{ string_duration|parse_duration }}
Returns the first non-NULL item.
from django_extra_tools.db.models.aggregates import First
Table.objects.aggregate(First('col1', order_by='col2'))
Returns the last non-NULL item.
from django_extra_tools.db.models.aggregates import Last
Table.objects.aggregate(Last('col1', order_by='col2'))
Returns median value.
from django_extra_tools.db.models.aggregates import Median
Table.objects.aggregate(Median('col1'))
Combines the values as the text. Fields are separated by a "separator".
from django_extra_tools.db.models.aggregates import StringAgg
Table.objects.aggregate(StringAgg('col1'))
Add created_at
field to model.
from django.db import models
from django_extra_tools.db.models import timestampable
class MyModel(timestampable.CreatedAtMixin, models.Model):
pass
model = MyModel()
print(model.created_at)
Add created_by
field to model.
from django.contrib.auth.models import User
from django.db import models
from django_extra_tools.db.models import timestampable
class MyModel(timestampable.CreatedByMixin, models.Model):
pass
user = User.objects.get(username='user')
model = MyModel(created_by=user)
print(model.created_by)
Add updated_at
field to model.
from django.db import models
from django_extra_tools.db.models import timestampable
class MyModel(timestampable.UpdatedAtMixin, models.Model):
operation = models.CharField(max_length=10)
model = MyModel()
print(model.updated_at)
model.operation = 'update'
model.save()
print(model.updated_at)
Add updated_by
field to model.
from django.contrib.auth.models import User
from django.db import models
from django_extra_tools.db.models import timestampable
class MyModel(timestampable.UpdatedByMixin, models.Model):
operation = models.CharField(max_length=10)
user = User.objects.get(username='user')
model = MyModel()
print(model.updated_by)
model.operation = 'update'
model.save_by(user)
print(model.updated_by)
Add deleted_at
field to model.
from django.db import models
from django_extra_tools.db.models import timestampable
class MyModel(timestampable.DeletedAtMixin, models.Model):
pass
model = MyModel()
print(model.deleted_at)
model.delete()
print(model.deleted_at)
Add deleted_by
field to model.
from django.contrib.auth.models import User
from django.db import models
from django_extra_tools.db.models import timestampable
class MyModel(timestampable.DeletedByMixin, models.Model):
pass
user = User.objects.get(username='user')
model = MyModel()
print(model.deleted_by)
model.delete_by(user)
print(model.deleted_by)
Add created_at
and created_by
fields to model.
Add updated_at
and updated_by
fields to model.
Add deleted_at
and deleted_by
fields to model.
Returns a (start, end, total, queryset) tuple for each batch in the given queryset.
from django_extra_tools.db.models import batch_qs
qs = Table.objects.all()
start, end, total, queryset = batch_qs(qs, 10)
Return tuple with PostgreSQL version of a specific connection.
from django_extra_tools.db.models import pg_version
version = pg_version()
An HTTP response class with the "download file" headers.
from django_extra_tools.http import HttpResponseGetFile
return HttpResponseGetFile(filename='file.txt', content=b'file content', content_type='file/text')
Get the client IP from the request.
from django_extra_tools.wsgi_request import get_client_ip
ip = get_client_ip(request)
You can configure list of local IP's by setting PRIVATE_IPS_PREFIX
PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', )
A management command which will be run only one instance of command with
name name
. No other command with name name
can not be run in the
same time.
from django_extra_tools.management import OneInstanceCommand
class Command(OneInstanceCommand):
name = 'mycommand'
def handle_instance(self, *args, **options):
# some operations
def lock_error_handler(self, exc):
# Own error handler
super(Command, self).lock_error_handler(exc)
A management command which perform a Nagios check.
from django_extra_tools.management import NagiosCheckCommand
class Command(NagiosCheckCommand):
def handle_nagios_check(self, *args, **options):
return self.STATE_OK, 'OK'
This middleware allows cross-domain XHR using the html5 postMessage API.
MIDDLEWARE_CLASSES = (
...
'django_extra_tools.middleware.XhrMiddleware'
)
XHR_MIDDLEWARE_ALLOWED_ORIGINS = '*'
XHR_MIDDLEWARE_ALLOWED_METHODS = ['POST', 'GET', 'OPTIONS', 'PUT', 'DELETE']
XHR_MIDDLEWARE_ALLOWED_HEADERS = ['Content-Type', 'Authorization', 'Location', '*']
XHR_MIDDLEWARE_ALLOWED_CREDENTIALS = 'true'
XHR_MIDDLEWARE_EXPOSE_HEADERS = ['Location']
Allow to login to user account through superuser login and password.
Add ThroughSuperuserModelBackend
to AUTHENTICATION_BACKENDS
:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'django_extra_tools.auth.backends.ThroughSuperuserModelBackend',
)
Optionally You can configure username separator (default is colon):
AUTH_BACKEND_USERNAME_SEPARATOR = ':'
Now You can login to user account in two ways:
- provide username='user1' and password='user password'
- provide username='superuser username:user1' and password='superuser password'
To create "Can view [content type name]" permissions for all content types just add
django_extra_tools.auth.view_permissions
at the end of INSTALLED_APPS
INSTALLED_APPS = [
…
'django_extra_tools.auth.view_permissions'
]
and run migration
python manage.py migrate
Function to set lock hook.
from django_extra_tools.lockers import lock
lock('unique_lock_name')
Next usage of lock on the same lock name raises LockError
exception.
You can configure locker mechanism through DEFAULT_LOCKER_CLASS
settings or directly:
from django_extra_tools.lockers import FileLocker
lock = FileLocker()('unique_lock_name')
This is a default locker.
This locker creates a unique_lock_name.lock file in temp directory.
You can configure this locker through settings:
DEFAULT_LOCKER_CLASS = 'django_extra_tools.lockers.FileLocker'
This locker creates a locker-unique_lock_name key in cache.
You can configure this locker through settings:
DEFAULT_LOCKER_CLASS = 'django_extra_tools.lockers.CacheLocker'