Model registration that uses a django.contrib.sites.models.Site object in the Queryset filter causes error

51 views
Skip to first unread message

Patrick Heneghan

unread,
Jan 15, 2017, 8:22:33 AM1/15/17
to django-watson discussion group
Hi there,

I'm having a problem when trying to use a Site object (from django.contrib.sites) in one of my Watson model registrations. The problem line appears to be the second line from the bottom in my apps.py:

from django.apps import AppConfig
from django.conf import settings

from watson import search

from easy_thumbnails.signals import saved_file
from easy_thumbnails.signal_handlers import generate_aliases_global

class PostsConfig(AppConfig):
   name = 'posts'
   def ready(self):

        from django.contrib.sites.models import Site

        saved_file.connect(generate_aliases_global)

        NewsItem = self.get_model('NewsItem')
       Article = self.get_model('Article')
       Page = self.get_model('Page')
       Event = self.get_model('Event')
       SpektrixEvent = self.get_model('SpektrixEvent')

        search.register(NewsItem.objects.filter(post_status='active'))
       search.register(Article.objects.filter(post_status='active'))
       search.register(Page.objects.filter(post_status='active'))
       search.register(Event.objects.get_upcoming_events(site=Site.objects.get_current(), include_spektrix=False))
       search.register(SpektrixEvent.objects.get_upcoming_events(site=Site.objects.get(id=settings.SITE_ID)))


The traceback:

Traceback (most recent call last):

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute

  return self.cursor.execute(sql, params)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/backends/sqlite3/base.py", line 337, in execute

  return Database.Cursor.execute(self, query, params)

sqlite3.OperationalError: no such table: django_site


The above exception was the direct cause of the following exception:


Traceback (most recent call last):

File "manage.py", line 22, in <module>

  execute_from_command_line(sys.argv)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line

  utility.execute()

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 341, in execute

  django.setup()

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/__init__.py", line 27, in setup

  apps.populate(settings.INSTALLED_APPS)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/apps/registry.py", line 115, in populate

  app_config.ready()

File "/Users/patrick/Documents/Development/my-project/source/my_project/posts/apps.py", line 30, in ready

  search.register(Event.objects.get_upcoming_events(site=Site.objects.get_current(), include_spektrix=False))

File "/Users/patrick/Documents/Development/my-project/source/my_project/posts/models.py", line 253, in get_upcoming_events

  events = events.filter(site=Site.objects.get(id=site_id))

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/models/manager.py", line 85, in manager_method

  return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/models/query.py", line 379, in get

  num = len(clone)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/models/query.py", line 238, in __len__

  self._fetch_all()

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/models/query.py", line 1087, in _fetch_all

  self._result_cache = list(self.iterator())

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/models/query.py", line 54, in __iter__

  results = compiler.execute_sql()

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/models/sql/compiler.py", line 835, in execute_sql

  cursor.execute(sql, params)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 79, in execute

  return super(CursorDebugWrapper, self).execute(sql, params)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute

  return self.cursor.execute(sql, params)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/utils.py", line 94, in __exit__

  six.reraise(dj_exc_type, dj_exc_value, traceback)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise

  raise value.with_traceback(tb)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute

  return self.cursor.execute(sql, params)

File "/Users/patrick/Documents/Development/my-project/venv/lib/python3.4/site-packages/django/db/backends/sqlite3/base.py", line 337, in execute

  return Database.Cursor.execute(self, query, params)

django.db.utils.OperationalError: no such table: django_site


The problem appears to be that the code is trying to use the sites framework before the django_site table has had a chance to be built by the migrations. This is backed up by the fact that I only experience this error after deleting the db and migrating it from scratch - or running unit tests, which do the same thing.

Interestingly, during unit tests, if the *development* db (the one pointed to in settings.py) is already in place, then the code in apps.py can be run against that db, and then the unit testing framework is able to move onto the task of creating it's own *testing* db, using the migrations.

I have tried refactoring this line (and its respective Manager method):
search.register(Event.objects.get_upcoming_events(site=Site.objects.get_current(), include_spektrix=False))
to this:
search.register(Event.objects.get_upcoming_events(site_id=settings.SITE_ID, include_spektrix=False))
...in other words, passing the site id as an int, rather than an actual Site object, but this also causes the same error. (I wondered whether doing this might delay the query to the django_site table, but it seems not.) 

Is there somewhere else I could register my models with Watson, such that the code would be run post-migration?

A workaround is to comment out the line of code that requires the Site object, then put it back in after the migration - but this is clunky, and I do often delete my db and re-migrate from scratch.

Any ideas as to what I could do?

Best,
Patrick

Dave Hall

unread,
Jan 16, 2017, 5:03:26 AM1/16/17
to django-watson discussion group
I'm really surprised that the ready() method is being run before migrations. I thought the point of the ready() method was that it was run when everything was... ready...?

The alternative is to pass the same filtered event queryset to watson.search() or watson.filter(), rather than passing it to the register method.

--
You received this message because you are subscribed to the Google Groups "django-watson discussion group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-watso...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-watson.
For more options, visit https://groups.google.com/d/optout.

Patrick Heneghan

unread,
Jan 16, 2017, 9:01:36 AM1/16/17
to django-watson discussion group
Perhaps it runs when this particular app is ready... but not necessarily before *all* apps are ready? The model I'm trying to access is from the django.contrib.sites app. Perhaps that app is not ready yet? My app ('posts') is listed after 'django.contrib.sites' in INSTALLED_APPS, but that doesn't seem to matter.

Just speculation.
Reply all
Reply to author
Forward
0 new messages