The following snippet allows readline-style tab completion backed onto Django models. I am using this in management commands in preference to specifying primary keys as arguments.
class QuerySetCompleter(object): def __init__(self, qs, field): self.qs = qs self.field = field self.prefix = None def __call__(self, prefix, index): if prefix != self.prefix: qs = self.qs.values_list(self.field, flat=True) if prefix: qs = qs.filter(**{ '%s__startswith' % self.field: prefix, }) self.matching = list(qs) self.prefix = prefix try: return self.matching[index] except IndexError: return None
Example usage:
import readline from mymodels import MyModel completer = QuerySetCompleter(MyModel.objects.all(), 'name') readline.set_completer(completer) readline.parse_and_bind("tab: complete") readline.set_completer_delims('') while 1: print repr(raw_input(">>> "))
Pressing <tab> at this >>> prompt will complete from the name field of the MyModel model just like a regular shell would.
We call readline.set_completer_delims as our items may contain word delimeters - otherwise readline would attempt a seperate completion of (eg) "Bar" if one of our items was "Foo Bar".