Django YOLOQuery
LLM‑Based Queries for the Django ORM
⚠️ This is just a Proof-of-Concept
Why?
I want to see how badly LLMs can be integrated into our system
TL;DR
authors = Author.objects.ai_query("get all authors named John")
books = Book.objects.ai_query("books published after 2020 by American authors")
recent = Author.objects.ai_query("authors with books published in the last 5 years")
Install
pip install django-yoloquery
Configure
Add to INSTALLED_APPS and set a few knobs in settings.py.
INSTALLED_APPS = [
# ... your apps ...
'django_yoloquery',
]
# Required: OpenAI API key (or set env OPENAI_API_KEY)
YOLOQUERY_OPENAI_API_KEY = "sk-..."
# Optional (shown with defaults)
YOLOQUERY_SCHEMA_DEPTH = 1 # how far to traverse relations
YOLOQUERY_INCLUDE_REVERSE = True # include reverse relations (related_name / _set)
YOLOQUERY_LLM_MODEL = "gpt-4o-mini" # pick your OpenAI model
YOLOQUERY_AUTO_INSTALL = ["myapp.*"] # auto‑YOLO patch models
🔑 If
YOLOQUERY_OPENAI_API_KEYis not set, YOLOQuery falls back to theOPENAI_API_KEYenvironment variable.
Manual Wiring (if you don’t want auto‑patch)
from django.db import models
from django_yoloquery import YoloManager
class Author(models.Model):
name = models.CharField(max_length=200)
country = models.CharField(max_length=100)
birth_date = models.DateField()
objects = YoloManager() # manual install
class Book(models.Model):
title = models.CharField(max_length=200)
authors = models.ManyToManyField(Author, related_name="books")
published_date = models.DateField()
isbn = models.CharField(max_length=13)
Auto‑Installation Patterns
YOLOQuery can monkey‑patch all the things at startup. Patterns are case‑sensitive app labels; model name matching is case‑insensitive.
YOLOQUERY_AUTO_INSTALL = [
"myapp.*", # all models in myapp
"blog.Post", # just that one model
"*", # YOLO EVERYTHING (seriously?)
]
When auto‑installed:
- The model’s default manager (
.objects) is replaced with a YOLO manager. - The original manager is saved as
._orig_objects. - A
.yoloalias also points at the YOLO manager because branding.
What the LLM Sees
YOLOQuery builds a JSON description of your model + related models (depth configurable, reverse rels optional). Example schema snippet for Author:
{
"root_model": "Author",
"app_label": "myapp",
"models": {
"Author": {
"fields": {
"name": {"type": "CharField", "null": false},
"country": {"type": "CharField", "null": false},
"birth_date": {"type": "DateField", "null": false}
},
"relationships": {
"books": {"type": "REV", "to": "Book"}
}
},
"Book": {
"fields": {
"title": {"type": "CharField", "null": false},
"published_date": {"type": "DateField", "null": false}
},
"relationships": {
"authors": {"type": "M2M", "to": "Author"}
}
}
}
}
Structured JSON Contract
The model must return JSON like:
{
"status": "ok",
"logic": "and", // or "or"
"filters": [
{"path": "name", "op": "iexact", "value": "John"},
{"path": "books__published_date", "op": "gt", "value": "2020-01-01"}
],
"order_by": ["-published_date"], // optional
"limit": 10 // optional
}
If the request can’t be translated (missing info / nonsense / hallucination danger), the model must respond:
{"status": "error", "message": "Missing value for field 'name'"}
YOLOQuery will turn that into an AIQueryLLMError (attached to an empty QuerySet unless raise_errors=True).
Supported Query Concepts
| You Say | LLM Might Output | Django Filters | |
|---|---|---|---|
| "authors named john" | name iexact John |
name__iexact="John" |
|
| "authors from usa or canada" | logic=or + country in [USA, Canada] | `Q(country__iexact="USA") | Q(country__iexact="Canada")` |
| "books published after 2020" | published_date gt 2020-01-01 | published_date__gt=date(2020,1,1) |
|
| "authors with books after 2020" | books__published_date gt 2020-01-01 | join across reverse M2M | |
| "top 10 newest books" | order_by=-published_date, limit=10 | .order_by('-published_date')[:10] |
Error Handling
YOLOQuery errs on the side of not doing something dumb:
qs = Author.objects.ai_query("authors where") # incomplete!
if hasattr(qs, 'ai_error'):
print("LLM said nope:", qs.ai_error)
Raise immediately:
Author.objects.ai_query("authors where", raise_errors=True)
# AIQueryLLMError: LLM could not translate query.
Testing (No API Calls)
from django_yoloquery import DummyLLM
DUMMY_RESPONSES = {
"authors named John": {
"status": "ok",
"filters": [{"path": "name", "op": "iexact", "value": "John"}]
},
"name is": {
"status": "error", "message": "Missing value for name"
},
}
dummy = DummyLLM(DUMMY_RESPONSES)
qs = Author.objects.ai_query("authors named John", llm=dummy)
assert list(qs.values_list("name", flat=True)) == ["John"]
FAQ (Frequently Asked Questions No One Asked Yet)
Q: Does this belong in production? A: The library literally has YOLO in the name.
Q: Will it leak my schema to OpenAI? A: Yes, that’s how it works. Use stub schemas or anonymized field names if that’s a problem.
Q: Can I use Anthropic / local models? A: PRs welcome. Right now it’s OpenAI only; we rely on JSON Schema format.
Q: What if the model hallucinates? A: We validate every field + op; hallucinations become errors instead of DB hits. (We try, anyway.)
Q: Does it understand dates like "last quarter"? A: Depends on the model; we just validate output.
Requirements
- Python 3.8+
- Django 3.2+
openai>=1.0.0- OpenAI API key
License
MIT – see LICENSE.
Metadata
Release files for django-yoloquery 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_yoloquery-0.1.4.tar.gz | 15.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_yoloquery-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.9 kB
Release files / django_yoloquery-0.1.4.tar.gz
| Download URL | django_yoloquery-0.1.4.tar.gz |
|---|---|
| Size | 15.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a389c378bdbc069bb3a1dcc301d2823a3cefc693c7f1e0f7a0be17a130d6f058
|
|
BLAKE2b-256 checksum How to use checksums |
d06e20673cefdffa636ed3ea5de37b884bf6587a8497ead6d61bd4263bc960fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 18, 2025.
Transparency logRelease files / django_yoloquery-0.1.4-py3-none-any.whl
| Download URL | django_yoloquery-0.1.4-py3-none-any.whl |
|---|---|
| Size | 13.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fb91bef4049762c43e9e1a26d59919939d3a4a33c088720dff1e9417ca9b0ae8
|
|
BLAKE2b-256 checksum How to use checksums |
034e06ff08ed27c43b88400ad5624a14f8504d132410fdf77d6178c43bdd8d4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 18, 2025.
Transparency log