Cannot delete an item from the Django admin interface

My lab built a Django website, which we’ve long used without a problem. Django is great!

We recently used the Django admin interface to create some content (a ‘Talk’ model) and upload a file. The upload failed with a Server Timeout Error (500). Now, we cannot delete or even click on the talk in the admin interface. Despite my best attempts, I can’t seem to figure out what’s wrong. I still feel like a Django beginner. I’m hoping someone can help.

See screenshot:

When we click on the item, we get a Server Error (500) message and Django outputs the following to our log files:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 850, in _resolve_lookup
    (bit, current))  # missing attribute
django.template.base.VariableDoesNotExist: Failed lookup for key [non_field_errors] in None
DEBUG 2021-10-23 07:29:00,382 base 128 140297891723008 Exception while resolving variable 'non_field_errors' in template 'admin/change_list.html'.
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 829, in _resolve_lookup
    current = current[bit]
TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 837, in _resolve_lookup
    current = getattr(current, bit)
AttributeError: 'NoneType' object has no attribute 'non_field_errors'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 843, in _resolve_lookup
    current = current[int(bit)]
ValueError: invalid literal for int() with base 10: 'non_field_errors'

When we try to delete the item, we receive a slightly different error:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 843, in _resolve_lookup
    current = current[int(bit)]
ValueError: invalid literal for int() with base 10: 'non_field_errors'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 850, in _resolve_lookup
    (bit, current))  # missing attribute
django.template.base.VariableDoesNotExist: Failed lookup for key [non_field_errors] in None
DEBUG 2021-10-23 07:21:19,130 base 128 140297916901120 Exception while resolving variable 'non_field_errors' in template 'admin/change_list.html'.
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/template/base.py", line 829, in _resolve_lookup
    current = current[bit]
TypeError: 'NoneType' object is not subscriptable

We are using Django version 2.1.15 with Python 3.8.

The modeladmin for this model is:

class TalkAdmin(admin.ModelAdmin):
    # The list display lets us control what is shown in the default talk table at Home > Website > Talk
    # See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display
    list_display = ('title', 'date', 'get_speakers_as_csv', 'forum_name', 'location', 'talk_type')

    # search_fields are used for auto-complete, see:
    #   https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.autocomplete_fields
    # for example, the PublicationAdmin uses auto-complete select2 for talks
    search_fields = ['title', 'forum_name']

    # Filters speakers only to current members and collaborators and sorts by first name
    # Based on: https://stackoverflow.com/a/17457828
    # Update: we no longer do this because sometimes we want to add a talk by a former member or collaborator
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        print("TalkAdmin.formfield_for_manytomany: db_field: {} db_field.name {} request: {}".format(db_field, db_field.name, request))
        if db_field.name == "projects":
            kwargs["widget"] = widgets.FilteredSelectMultiple("projects", is_stacked=False)
        if db_field.name == "project_umbrellas":
            kwargs["widget"] = widgets.FilteredSelectMultiple("project umbrellas", is_stacked=False, )
        if db_field.name == "speakers":
            # Uncomment the following block of code to limit the speakers field in the admin UI only to current lab members
            # Note: we don't actually want to do this (see https://github.com/jonfroehlich/makeabilitylabwebsite/issues/534)
            # but keeping it here because code may be useful in the future for other areas of admin interface
            # current_member_and_collab_ids = [person.id for person in Person.objects.all() if person.is_current_member()]
            # filtered_speakers = Person.objects.filter(id__in=current_member_and_collab_ids).order_by('first_name')
            # kwargs["queryset"] = filtered_speakers
            kwargs["widget"] = widgets.FilteredSelectMultiple("speakers", is_stacked=False)
        if db_field.name == "keywords":
            kwargs["widget"] = widgets.FilteredSelectMultiple("keywords", is_stacked=False)
        return super(TalkAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

In case it’s useful, the code is here: GitHub - makeabilitylab/makeabilitylabwebsite: The Makeability Lab website

Django 2.1 is not identified as being compatible with Python 3.8 - Django 2.1 release notes | Django documentation | Django

Django 2.2 doesn’t achieve Python 3.8 compatibility until 2.2.8 - Django 2.2 release notes | Django documentation | Django

Ugh, very good catch @KenWhitesell. I note that this problem was occurring before we upgraded Python versions…

But I’m hoping to upgrade to a more recent Django version soon.

And to be clear, I’m not saying that the cause of the errors are related to the Python version. But it is another variable in the mix.

If I’m reading it correctly, this is happening with only one instance of the Talks model?

Do you have other instances of Talk that are not exhibiting this problem?

At this point, I’d start with the standard list of diagnostic practices.

  • Any recent changes?

  • Can you verify that the database is correct?

  • Have you restarted the project? (A 500 could be a very messy situation)

  • Can you replicate the issue in a test environment?

A form’s non_field_errors attribute is a method returning errors not associated with a particular field. See The Forms API | Django documentation | Django. From the error message, it almost looks like it was replaced by a different object.

1 Like

Thanks @KenWhitesell.

No other instances of Talk are exhibiting this problem. We did not have any recent code changes precipitating the problem. If I had to speculate, I would say something happened to, possibly, make the backend database into an inconsistent state when the student tried to upload their talk (and received a timeout).

I was thinking of trying to verify the database. I agree that’s the best next step.

Thank you,

Jon

1 Like