DjangoQL
DjangoQL is an advanced search language for Django, providing auto-completion and supporting logical operators, parentheses, table joins, and working with any Django model. The current version is 0.19.1, and it is actively maintained with regular updates. It's tested against a wide range of Python (2.7, 3.6–3.14) and Django (1.8–6.0) versions.
Warnings
- breaking In version 0.14.0, the signature of `DjangoQLField.get_options()` changed to accept a mandatory `search` parameter. If you implemented custom suggestion options for your schema, you must update the method to handle this parameter and return results matching the search criteria.
- breaking Starting from version 0.14.0, the DjangoQL checkbox in the admin, which enables the advanced search, is on by default. If this is not desired, the behavior can be turned off.
- deprecated As of version 0.14.0, `DjangoQLSchema.as_dict()` is deprecated. Users should switch to the new schema serializers provided in `djangoql.serializers`.
- gotcha When defining custom `DjangoQLSchema` with `suggest_options`, if a model field does not have `choices` specified, DjangoQL will synchronously pull *all* distinct values for that field. This can lead to significant performance issues and memory consumption with large querysets.
- gotcha DjangoQL queries are case-sensitive. This differs from some common database search behaviors and might lead to unexpected results if not accounted for.
- gotcha Older versions of DjangoQL (e.g., prior to 0.19.0, specifically around 0.3.1, 0.17.0, 0.17.1 based on search results) strictly required string values to be enclosed in double quotes. Newer versions now support both single and double quotes. This inconsistency could be a migration challenge or cause confusion for users familiar with older syntax.
- gotcha If no custom `DjangoQLSchema` is specified, DjangoQL will generate a default schema by recursively walking through all model fields and relations. While convenient, this can expose more data than intended for security reasons or lead to inefficient queries on large, complex models.
Install
-
pip install djangoql
Imports
- DjangoQLSearchMixin
from djangoql.admin import DjangoQLSearchMixin
- DjangoQLQuerySet
from djangoql.queryset import DjangoQLQuerySet
- apply_search
from djangoql.queryset import apply_search
- DjangoQLSchema
from djangoql.schema import DjangoQLSchema
Quickstart
import os
import django
from django.conf import settings
from django.db import models
from django.contrib import admin
# Minimal Django setup (usually done in settings.py)
if not settings.configured:
settings.configure(
INSTALLED_APPS=[
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'djangoql', # Add djangoql to installed apps
'myapp' # A dummy app for models
],
DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
ROOT_URLCONF=__name__,
SECRET_KEY='super-secret',
TEMPLATES=[
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
],
STATIC_URL='/static/',
)
django.setup()
# myapp/models.py
class Book(models.Model):
title = models.CharField(max_length=255)
author = models.CharField(max_length=100)
published_year = models.IntegerField(default=2000)
in_stock = models.BooleanField(default=True)
def __str__(self):
return self.title
# myapp/admin.py
from djangoql.admin import DjangoQLSearchMixin
class BookAdmin(DjangoQLSearchMixin, admin.ModelAdmin):
list_display = ('title', 'author', 'published_year', 'in_stock')
search_fields = ('title', 'author') # Optional: enables standard Django search alongside DjangoQL
admin.site.register(Book, BookAdmin)
# Example of using DjangoQLQuerySet outside admin
from djangoql.queryset import DjangoQLQuerySet
class BookQuerySet(DjangoQLQuerySet):
pass
Book.add_to_class('objects', BookQuerySet.as_manager())
# To demonstrate, run `python manage.py createsuperuser` and then `python manage.py runserver`
# Navigate to /admin/myapp/book/ to see DjangoQL in action.
# Example query in DjangoQL search bar: `author = "Tolkien" and published_year > 1950`