I’m working on a Django app that needs to perform operations on specified model fields.
Django already has a calling style for referencing model fields with query constraints — multiple terms are composed into predicates with double-underscores and passed as keyword args. Queryset filtering, using QuerySet.filter() and Q(), make use of this syntax e.g.:
stuff = MyStuff.objects.filter(name__isnull=False)
thing = MyStuff.objects.filter(Q(name__icontains="yo") & Q(ptype__iendswith="dogg")).get()
The same syntax is used by F() expressions, which are used to build dynamic predicates in query statements. The majority Django users have seen (if not used) this syntax in some form.
I would like to create a similar dynamically-evaluated, composeable Python idiom — for this question’s sake I’ll call it G() — that uses the same syntax, to furnish a similar handle for a lazily-evaluated field lookup instance that can be logically recombined with other such instances.
How ought one approach this task? Both Q() and F() are subclasses of django.utils.tree.Node — at least they are in Django 1.4 (they weren’t always implemented as they are now, and their interface may or may not be private). Much of the kwarg-filter-expression action takes place in django.db.models.sql.Query, I believe… which that is an enormous and daunting class with illegible couplings to myriad bits of the ORM’s guts.
I’m reasonably sure the query-filter syntax can be accomplished much more simply than I’m imagining. Where should I begin?
Thanks in advance.
I’m not exactly sure what you’re trying to do with the double-underscored-keywords, but the simplest place to start would probably be here:
From there, I guess it depends on what you’re going to do with that information. Hope this helps!