opensafely-core / opensafely-core/opencodelists

`superusers.index` view 500s and maybe isn't useful

Open
#2,444 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
60
Forks
16
Avg merge
4d 12h
Merged PRs (30d)
17

Description

Why are we doing this?

There is a superusers app with an index page that tries to list all organizations, users, and their codelists. This shows some extra info over the main index/home page which only shows codelists attached to an organisation. However, it currently doesn't work against the production database, returning a 500 error. And it's not clear if it's useful/used. Why do we need this view on codelists? Is anyone using it (presumably not, as it's broken. Would anyone like to?).

Maybe we should have an admin view on the site, but if so it might not look like this one and we might want to design it from scratch. Also, I'd rather we build it by extending the Django-provided django.contrib.admin, which is very robust, flexible, and probably supports our needs.

Sentry error (triggered by Mike).

The URL on the prod site: https://www.opencodelists.org/superusers/

How will we know when it's done?

We've figured out if anyone uses this view and would like it working (check Sentry/Honeycomb for accesses, ask in #general?).

The page either works in production, or the app has been removed.

Possibly future issues created for admin functionality on the site.

What are we doing?

As above, TBD.

Example stacktrace from local dev:

2025-04-17T10:33:18.271360Z [error    ] Internal Server Error: /superusers/ [django.request] ip=127.0.0.1 request_id=bcd51dd6-e5e4-42f5-ab67-7a94bc2733d1 user_id=adminme
Traceback (most recent call last):
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/contrib/auth/decorators.py", line 60, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/superusers/views.py", line 43, in index
    return render(request, "superusers/index.html", ctx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/shortcuts.py", line 25, in render
    content = loader.render_to_string(template_name, context, request, using=using)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
    return self.template.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
    return self._render(context)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 1008, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 969, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
    return compiled_parent._render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 1008, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 969, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
    result = block.nodelist.render(context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 1008, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 969, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 243, in render
    nodelist.append(node.render_annotated(context))
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 969, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 243, in render
    nodelist.append(node.render_annotated(context))
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 969, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 210, in render
    return template.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 173, in render
    return self._render(context)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 1008, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 969, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 243, in render
    nodelist.append(node.render_annotated(context))
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 969, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 1067, in render
    output = self.filter_expression.resolve(context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 718, in resolve
    obj = self.var.resolve(context)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 850, in resolve
    value = self._resolve_lookup(context)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/template/base.py", line 917, in _resolve_lookup
    current = current()
              ^^^^^^^^^
  File "/home/mike/opencodelists/codelists/models.py", line 306, in get_absolute_url
    return reverse(
           ^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/urls/base.py", line 88, in reverse
    return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/opencodelists/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'user_version' with keyword arguments '{'username': 'ramosjeffrey', 'codelist_slug': '', 'tag_or_hash': '1d21a426'}' not found. 1 pattern(s) tried: ['codelist/user/(?P<username>[^/]+)/(?P<codelist_slug>[^/]+)/(?P<tag_or_hash>[^/]+)/\\Z']
2025-04-17T10:33:18.272842Z [error    ] "GET /superusers/ HTTP/1.1" 500 661825 [django.server]

Defining delivery tasks guidance

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with superusers/views.py and the superusers/index.html template, then inspect codelists/models.py at get_absolute_url and the user_version URL pattern. Use the Sentry stack trace to reproduce the production failure and check Sentry or Honeycomb for usage, with the project discussion deciding whether to fix or remove the app. Done means the view works in production or the app has been removed.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.