Skip to main content

LLM-backed, structured JSON output, schema-aware natural language queries for Django ORM

Project description

Django YOLOQuery

LLM‑Based Queries for the Django ORM

⚠️ This is just a Proof-of-Concept

PyPI version Python versions Django versions


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_KEY is not set, YOLOQuery falls back to the OPENAI_API_KEY environment 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 .yolo alias 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_yoloquery-0.1.4.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_yoloquery-0.1.4-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file django_yoloquery-0.1.4.tar.gz.

File metadata

  • Download URL: django_yoloquery-0.1.4.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for django_yoloquery-0.1.4.tar.gz
Algorithm Hash digest
SHA256 a389c378bdbc069bb3a1dcc301d2823a3cefc693c7f1e0f7a0be17a130d6f058
MD5 1c07e750be68f26f655b5809e775339b
BLAKE2b-256 d06e20673cefdffa636ed3ea5de37b884bf6587a8497ead6d61bd4263bc960fe

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_yoloquery-0.1.4.tar.gz:

Publisher: release.yml on zhuang42/django-yoloquery

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_yoloquery-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for django_yoloquery-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 fb91bef4049762c43e9e1a26d59919939d3a4a33c088720dff1e9417ca9b0ae8
MD5 7f5e42b5495683dd9471c09562f430cd
BLAKE2b-256 034e06ff08ed27c43b88400ad5624a14f8504d132410fdf77d6178c43bdd8d4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_yoloquery-0.1.4-py3-none-any.whl:

Publisher: release.yml on zhuang42/django-yoloquery

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page