title: Custom lookup is not being registered in Django
body: <p>I've created a custom lookup. I'm using it for a query, however, when I do so, the error <code>Related Field got invalid lookup: lcb</code> is thrown.</p>
  
  <p>I'm assuming that this is because this custom lookup isn't being registered properly. As you'll see below, I've tried several things and I'm lost as to what the issue is.</p>
  
  <p>Here's my code:</p>
  
  <p><strong>tenants/views.py</strong></p>
  
  <pre><code>from main.lookups import *
  
  def find_tenants(request, house_id):
      house = HouseListing.objects.get(pk=house_id)
      applications = HousingApplication.objects.filter(date_from__gte=house.available_from)
      applications = applications.filter(pets__lcb=house.allowed_pets.values_list('id', flat=True))
  
      context = {'house': house, 'applications': applications}
      return render(request, 'landlords/find-tenants.html', context)
  </code></pre>
  
  <p><strong>main/lookups.py</strong></p>
  
  <pre><code>from django.db.models import Lookup, ManyToManyField
  
  
  # Custom lookups
  
  @ManyToManyField.register_lookup
  class ListContainedBy(Lookup):
      lookup_name = 'lcb'
  
      def as_sql(self, compiler, connection):
          lhs, lhs_params = self.process_lhs(compiler, connection)
          rhs, rhs_params = self.process_rhs(compiler, connection)
          params = lhs_params + rhs_params
          return '%s &lt;@ %s' % (lhs, rhs), params
  </code></pre>
  
  <p>I find this very strange, as <a href="https://docs.djangoproject.com/en/1.10/howto/custom-lookups/" rel="nofollow noreferrer">the docs</a> suggest registering the lookup in the <code>AppConfig</code>, or in <code>models.py</code>. I've tried both of these things and neither worked.</p>
  
  <p><strong>Traceback</strong></p>
  
  <pre><code>Environment:
  
  
  Request Method: GET
  Request URL: http://127.0.0.1:8000/landlords/find-tenants/5/
  
  Django Version: 1.10.2
  Python Version: 2.7.12
  Installed Applications:
  ['main.apps.MainConfig',
   'tenants.apps.TenantsConfig',
   'landlords.apps.LandlordsConfig',
   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
   'django.contrib.humanize',
   'django.contrib.postgres',
   'imagekit']
  Installed Middleware:
  ['django.middleware.security.SecurityMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.common.CommonMiddleware',
   'django.middleware.csrf.CsrfViewMiddleware',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
   'django.contrib.messages.middleware.MessageMiddleware',
   'django.middleware.clickjacking.XFrameOptionsMiddleware']
  
  
  
  Traceback:
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
    39.             response = get_response(request)
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/core/handlers/base.py" in _legacy_get_response
    249.             response = self._get_response(request)
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
    187.                 response = self.process_exception_by_middleware(e, request)
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
    185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
    23.                 return view_func(request, *args, **kwargs)
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
    23.                 return view_func(request, *args, **kwargs)
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/housingfinder/landlords/views.py" in find_tenants
    132.     applications = applications.filter(pets__lcb=house.allowed_pets.values_list('id', flat=True))
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/query.py" in filter
    796.         return self._filter_or_exclude(False, *args, **kwargs)
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/query.py" in _filter_or_exclude
    814.             clone.query.add_q(Q(*args, **kwargs))
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/sql/query.py" in add_q
    1227.         clause, _ = self._add_q(q_object, self.used_aliases)
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/sql/query.py" in _add_q
    1253.                     allow_joins=allow_joins, split_subq=split_subq,
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/sql/query.py" in build_filter
    1178.             lookup_class = field.get_lookup(lookups[0])
  
  File "/Users/mightyspaj/Development/Projects/housingfinder/lib/python2.7/site-packages/django/db/models/fields/related.py" in get_lookup
    694.             raise TypeError('Related Field got invalid lookup: %s' % lookup_name)
  
  Exception Type: TypeError at /landlords/find-tenants/5/
  Exception Value: Related Field got invalid lookup: lcb
  </code></pre>
  
  <p><strong>All the things I've tried so far</strong></p>
  
  <ol>
  <li>Registering the lookup in the <code>MainConfig.ready()</code> function</li>
  <li>Registering the lookup in the <code>find_tenants()</code> view</li>
  <li>Registering the lookup in <code>main/models.py</code></li>
  <li>Registering the lookup as a <code>Field</code> instead of a <code>ManyToManyField</code></li>
  <li>Registering the lookup using <code>ManyToManyField.register_lookup()</code> instead of a decorator</li>
  <li>Changing <code>%s &lt;@ %s</code> to <code>%s = %s</code>. I thought the issue might be that it thinks my SQL is invalid</li>
  </ol>