openlibhums / janeway

A web-based platform for publishing journals, preprints, conference proceedings, and books
https://janeway.systems/
GNU Affero General Public License v3.0
168 stars 63 forks source link

CMS page for certain journals returns MultipleObjectsReturned at /cms/ #1917

Closed hachacha closed 3 years ago

hachacha commented 3 years ago

Describe the bug This was discovered shortly after the last update to 1.3.8-RC-2 but it may have been happening before.

When navigating to the /cms/ editor for certain journals we get this error:

MultipleObjectsReturned at /cms/
get() returned more than one NavigationItem -- it returned 6!
Request Method: GET
Request URL:    http://localhost:8000/ETHOS/cms/

Janeway version 509b344b26075b2480872489903a4d3cd3282d8a

To Reproduce

  1. go to journal/cms

Expected behavior see cms page

Additional context

I feel like this has happened before elsewhere and have remedied it by deleting duplicate entries from the database somehow. This was for HomePageElements not for NavigationItem. I believe I should be looking in to the database at the cms_navigationitem table When I look at that table i see this with a few duplicates (ids 43,44):

 id | object_id |       link_name        |               link               | is_external | sequence | has_sub_nav | content_type_id | page_id | top_level_nav_id 
----+-----------+------------------------+----------------------------------+-------------+----------+-------------+-----------------+---------+------------------
  3 |         2 | About CMU LPS          | site/about                       | f           |       99 | f           |              64 |         |                 
  4 |         2 | Privacy Policy         | site/privacy                     | f           |       99 | f           |              64 |         |                 
  8 |         2 | About CMU LPS          | site/about                       | f           |       60 | f           |              48 |         |                 
  9 |         2 | Privacy Policy         | site/privacy                     | f           |       50 | f           |              48 |         |                 
 10 |         2 | List of Experts        | ETHOS/site/expertise             | f           |       40 | f           |              48 |         |                 
 12 |         2 | Submission Guidelines  | ETHOS/site/submission-guidelines | f           |       20 | f           |              48 |         |                 
 13 |         2 | About                  | ETHOS/site/about                 | f           |       10 | f           |              48 |         |                 
 11 |         2 | Editorial Team         | ETHOS/editorialteam              | f           |       30 | f           |              48 |         |                 
 31 |         3 | About the Journal      | LDR/site/aboutjournal            | f           |       21 | f           |              48 |         |               30
 30 |         3 | About                  | LDR/site/about                   | f           |       20 | t           |              48 |         |               30
 40 |         3 | About                  | LDR/site/about                   | f           |       99 | f           |              48 |         |               30
 28 |         3 | Research Integrity     | LDR/site/researchintegrity       | f           |       70 | f           |              48 |         |                 
 42 |         3 | Editorial Team         | LDR/site/editorialteams          | f           |       22 | f           |              48 |         |               15
 43 |         3 | Editorial Team         | LDR/site/editorialteams          | f           |       21 | f           |              48 |         |               15
 44 |         3 | Editorial Teams        | LDR/site/editorialteams          | f           |       21 | f           |              48 |         |               30
 45 |         3 | Editorial Team         | LDR/site/editorialteam           | f           |       21 | f           |              48 |         |               41
 46 |         3 | Editorial Policies     | LDR/site/editorialpolicies       | f           |       22 | f           |              48 |         |               41
 51 |         4 | Collections            | /collections/collection          | f           |       99 | f           |              48 |         |                 
 16 |         3 | About the Journal      | LDR/site/about                   | f           |       21 | f           |              48 |         |               15
 17 |         3 | Contact                | LDR/contact                      | f           |       22 | f           |              48 |         |               15
 18 |         3 | Editorial Team         | LDR/site/editorialteam           | f           |       23 | f           |              48 |         |               15
 29 |         3 | Editorial Policies     | LDR/site/editorialpolicies       | f           |       26 | f           |              48 |         |               15
 19 |         3 | Journal Management     | LDR/site/journalmanagement       | f           |       25 | f           |              48 |         |               15
 41 |         3 | About                  | LDR/site/aboutjournal/           | f           |       20 | t           |              48 |         |                 
 20 |         3 | Articles               | LDR/site/browsearticles          | f           |       30 | f           |              48 |         |                 
 15 |         3 | About                  | LDR/site/about                   | f           |       20 | t           |              48 |         |               15
 32 |         3 | Editorial Team         | LDR/site/editorialteam           | f           |       22 | f           |              48 |         |               30
 33 |         3 | Editorial Policies     | LDR/site/editorialpolicies       | f           |       23 | f           |              48 |         |               30
 34 |         3 | Journal Management     | LDR/site/journalmanagement       | f           |       24 | f           |              48 |         |               30
 24 |         3 | Article Guidelines     | LDR/site/articleguidelines       | f           |       41 | f           |              48 |         |               23
 49 |         3 | Author Guidelines      | LDR/site/authorguidelines        | f           |       42 | f           |              48 |         |               23
 26 |         3 | Reviewer Guidelines    | LDR/site/reviewerguidelines      | f           |       43 | f           |              48 |         |               23
 48 |         3 | Statistics and Methods | LDR/site/statistics              | f           |       44 | f           |              48 |         |               23
 23 |         3 | Guidelines             | LDR/site/articleguidelines       | f           |       40 | t           |              48 |         |                 
 27 |         3 | Open Science           | LDR/site/openscience             | f           |       50 | f           |              48 |         |

The strange thing is that wen going to the journal with the duplicates, LDR it loads just fine. But it does not work for our other journal, ETHOS). Is this something to o with the issue_types?

mauromsl commented 3 years ago

NavItems use django's implementation of generic foreign keys, which is (in)famous for not providing any integrity at the database level. I'll look into adding some further checks and the application level to avoid creating duplicate entries.

In the interim, can you share a bit of the stack trace were this is being raised? there are a few bits of logic in charge of fetching NavItems?

hachacha commented 3 years ago

It's a template error. Above the line where there's the error i see {#Custom Issue types navigation#}

Here's the full-on traceback

Environment:

Request Method: GET
Request URL: http://janeway-dev.library.cmu.edu/ETHOS/cms/

Django Version: 1.11.29
Python Version: 3.6.9
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize',
 'cms',
 'core',
 'copyediting',
 'cron',
 'events',
 'identifiers',
 'journal',
 'metrics',
 'comms',
 'preprint',
 'press',
 'production',
 'proofing',
 'review',
 'reports',
 'security',
 'submission',
 'transform',
 'utils',
 'install',
 'workflow',
 'django_summernote',
 'markdown_deux',
 'hvad',
 'raven.contrib.django.raven_compat',
 'bootstrap4',
 'rest_framework',
 'foundationform',
 'materialize',
 'snowpenguin.django.recaptcha2',
 'simplemathcaptcha',
 'django.forms',
 'plugins.back_content',
 'plugins.pandoc_plugin',
 'plugins.archive_plugin',
 'core.homepage_elements.about',
 'core.homepage_elements.carousel',
 'core.homepage_elements.featured',
 'core.homepage_elements.html',
 'core.homepage_elements.issue',
 'core.homepage_elements.journals',
 'core.homepage_elements.journals_and_html',
 'core.homepage_elements.news',
 'core.homepage_elements.popular',
 'core.homepage_elements.preprints']
Installed Middleware:
('raven.contrib.django.middleware.SentryMiddleware',
 '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',
 'django.middleware.security.SecurityMiddleware',
 'core.middleware.TimezoneMiddleware',
 'core.middleware.SiteSettingsMiddleware',
 'utils.template_override_middleware.ThemeEngineMiddleware',
 'core.middleware.MaintenanceModeMiddleware',
 'cron.middleware.CronMiddleware',
 'core.middleware.CounterCookieMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'core.middleware.PressMiddleware',
 'core.middleware.GlobalRequestMiddleware',
 'django.middleware.gzip.GZipMiddleware')

Template error:
In template /home/ulredcarpet/janeway/src/templates/admin/elements/cms_nav.html, error at line 29
   get() returned more than one NavigationItem -- it returned 6!   19 :                             <a class="tiny button" href="{% url 'cms_nav_edit' sub_nav.pk %}"><i class="fa fa-edit"></i></a>
   20 :                             <button class="tiny button" name="delete_nav" value="{{ sub_nav.pk }}">
   21 :                                 <i class="fa fa-times"></i>
   22 :                             </button>
   23 :                         </li>
   24 :                     {% endfor %}
   25 :                 </ul>
   26 :             {% endif %}
   27 :         {% endfor %}
   28 :         {#Custom Issue types navigation#}
   29 :          {% for issue_type, nav in collection_nav_items %} 
   30 :         <li>{{ issue_type.plural_name }}
   31 :             {% if nav %}
   32 :             <a class="tiny button" href="{% url 'cms_nav_edit' nav.pk %}"><i class="fa fa-edit"></i></a>
   33 :             {% endif %}
   34 :             <button class="tiny button" name="toggle_collection_nav" value="{{ issue_type.pk }}"><i class="fa fa-{% if nav %}times{% else %}check{% endif %}"></i>
   35 :         </li>
   36 :         {% endfor %}
   37 :         {% if request.journal %}
   38 :             <li>News
   39 :                 <button class="tiny button" name="nav" value="nav_news"><i

Traceback:

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/core/handlers/base.py" in _legacy_get_response
  249.             response = self._get_response(request)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/ulredcarpet/janeway/src/security/decorators.py" in wrapper
  63.             return func(request, *args, **kwargs)

File "/home/ulredcarpet/janeway/src/security/decorators.py" in wrapper
  167.             return func(request, *args, **kwargs)

File "/home/ulredcarpet/janeway/src/cms/views.py" in index
  80.     return render(request, template, context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/shortcuts.py" in render
  30.     content = loader.render_to_string(template_name, context, request, using=using)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/loader.py" in render_to_string
  68.     return template.render(context, request)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/backends/django.py" in render
  66.             return self.template.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render
  207.                     return self._render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
  107.     return self.nodelist.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  177.             return compiled_parent._render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
  107.     return self.nodelist.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  72.                 result = block.nodelist.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  216.                 return template.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render
  209.                 return self._render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/test/utils.py" in instrumented_test_render
  107.     return self.nodelist.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/template/defaulttags.py" in render
  172.                 values = list(values)

File "/home/ulredcarpet/janeway/src/cms/models.py" in get_content_nav_for_journal
  94.                     object_id=issue_type.pk,

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  85.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/home/ulredcarpet/.virtualenvs/janeway/lib/python3.6/site-packages/django/db/models/query.py" in get
  384.             (self.model._meta.object_name, num)

Exception Type: MultipleObjectsReturned at /cms/
Exception Value: get() returned more than one NavigationItem -- it returned 6!