It turns out that creating this custom lookup would be inefficient. For example, if the custom query looked like this:
id__custom='abc12'
Then the sql query would look like this:
WHERE 'abc12' LIKE id||%
However, this LIKE query would be very slow because it can't use any indexes. Every single record would have to be compared to 'abc12'. So the best way to achieve the same goal is to divide the string into substrings and store them in a list. Then you can search for those using the __in lookup.
For instance, if you wanted to find matches that contained at least half of the string you could create three substrings and search for those. By using the __in lookup your query would be much faster because you could use existing indexes. The result would look like this:
substrings = ['abc', 'abc1', 'abc12']
query = Item.objects.filter(id__in=substrings).values('id', 'manufacturer')