Opened 3 weeks ago

Closed 2 days ago

Last modified 2 days ago

#37187 closed Bug (fixed)

Extraneous and confusing ModelAdmin select_related deprecation warnings

Reported by: Mike Edmunds Owned by: Mike Edmunds
Component: contrib.admin Version: 6.1
Severity: Release blocker Keywords: ModelAdmin, deprecation
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Mike Edmunds)

Some of the deprecation warnings introduced in 122f0b62a1effa558aad67a62e5b0d84a49cdc23 (as a follow-up to #36593):

  • Are issued against Django internals or wsgiref/handlers.py (or whatever code is serving the admin site)—not against the code that is responsible for the deprecated behavior.
  • Sometimes include an extra warning that "Calling select_related() with no arguments is deprecated," even though select_related() is not called anywhere in the user's code.

To reproduce (Django 6.1b1, run with PYTHONWARNINGS=always to see all deprecations):

  1. Have a models.Author and models.Book with a foreign key to author.
  2. Define admin.BookAdmin with a get_select_related() method that returns the deprecated value True:
    from django.contrib import admin
    from .models import Author, Book
    
    class BookAdmin(admin.ModelAdmin):
        list_display = ['title', 'author__name']
    
        def get_list_select_related(self, request):
            return True  # deprecated return value
    
    admin.site.register(Author)
    admin.site.register(Book, BookAdmin)
    
  3. Run the devserver and visit /admin/yourapp/books/

Results: the warning about returning True from get_list_select_related() points to Django's internals, and there's an extra warning about wsgiref/handlers.py calling select_related() with no arguments:

.venv/lib/python3.14/site-packages/django/contrib/admin/options.py:930: RemovedInDjango70Warning: Returning True from ModelAdmin.get_list_select_related() is deprecated. Return False or a list or tuple of fields to fetch instead.
  warnings.warn(
.pyenv/versions/3.14.3/lib/python3.14/wsgiref/handlers.py:137: RemovedInDjango70Warning: Calling select_related() with no arguments is deprecated. Specify the fields to fetch instead.
  self.result = application(self.environ, self.start_response)

Expected: ideally, something that points to the BookAdmin implementation (and nothing about calling select_related()):

.../example-project/yourapp/admin.py:7: RemovedInDjango70Warning: Returning True from ModelAdmin.get_list_select_related() is deprecated. Return False or a list or tuple of fields to fetch instead.
  def get_list_select_related(self, request):

There are two issues here:

  1. ModelAdmin.get_changelist_instance() is trying to warn about an overridden subclass method that has already been called so is no longer on the stack. (It's also missing skip_file_prefixes, which is why it's blaming Django internals. But adding that would just move the blame to wsgiref—still not helpful.)
  2. QuerySet.select_related() is unconditionally issuing a deprecation warning, even when it's being used internally to implement a deprecated feature elsewhere in Django (like in ModelAdmin).

The second problem is easily solved: we implemented warn_about_external_use() specifically for this use case.

The first problem is probably solvable by using warnings.warn_explicit() to point to the subclass method that is actually at fault. (I'm looking into that now.) If that doesn't work, we could change the warning message to include the actual subclass name: Returning True from yourapp.admin.BookAdmin.get_list_select_related() is deprecated.

Also:

  • If you replace BookAdmin.get_list_select_related() with list_select_related = True, you get a nice startup-time warning that points at the class BookAdmin definition in your own admin.py. But you still get the extraneous select_related() warning in wsgiref when visiting the view.
  • If you load the admin view from a test, the warnings will point to the self.client.get("/admin/yourapp/books/") line instead of wsgiref. (That at least gives you some idea which code might be the problem.)
  • I suspect there's a similar issue with the warning for overriding get_actions()/get_action_choices() without the 'action_location' parameter (from #12090 - f30acb184f75fd9260cfd6ddc48a3bbbd49f9c1d).
  • The extraneous select_related() warning occurs in Django's tests, but is being suppressed by #37072. (The PR for that issue made it visible, and pulling that thread lead to this.)

Change History (15)

comment:1 by Mike Edmunds, 3 weeks ago

Description: modified (diff)

comment:2 by Jacob Walls, 3 weeks ago

Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

Nice catch!

comment:3 by Mike Edmunds, 3 weeks ago

warnings.warn_explicit() works well. I'm putting together a helper function for that, and will cover this and #37190 in the same PR.

comment:4 by Mike Edmunds, 3 weeks ago

Has patch: set

https://github.com/django/django/pull/21551 is the quick fix for the extra select_related() warning (problem "B").

comment:5 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

In 99672c6:

Refs #36593, #37187 -- Avoided spurious select_related() warning in ModelAdmin.

Changed QuerySet.select_related() "called with no arguments" deprecation
warning to be issued only when called from outside Django. This prevents
a confusing, cascading warning when ModelAdmin issues its own warning
for list_select_related=True (see 122f0b62) and then calls
QuerySet.select_related() to implement the deprecated behavior.

comment:6 by Mike Edmunds, 3 weeks ago

Has patch: unset

comment:7 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

In 1d20e124:

[6.1.x] Refs #36593, #37187 -- Avoided spurious select_related() warning in ModelAdmin.

Changed QuerySet.select_related() "called with no arguments" deprecation
warning to be issued only when called from outside Django. This prevents
a confusing, cascading warning when ModelAdmin issues its own warning
for list_select_related=True (see 122f0b62) and then calls
QuerySet.select_related() to implement the deprecated behavior.

Backport of 99672c672a1537aeb0d1fd5911ca6f04154cc091 from main.

comment:8 by Mike Edmunds, 3 weeks ago

Has patch: set

comment:9 by Jacob Walls, 3 weeks ago

Patch needs improvement: set

comment:10 by Mike Edmunds, 3 weeks ago

Patch needs improvement: unset

comment:11 by Jacob Walls, 3 days ago

Triage Stage: AcceptedReady for checkin

comment:12 by Jacob Walls <jacobtylerwalls@…>, 2 days ago

In 260d1369:

Refs #37187 -- Implemented warn_about_implementation() deprecation utility.

Created warn_about_implementation() for issuing warnings about
particular code that isn't currently on the call stack.

comment:13 by Jacob Walls <jacobtylerwalls@…>, 2 days ago

Resolution: fixed
Status: assignedclosed

In 2e48636c:

Fixed #37187, #37190 -- Pointed ModelAdmin warnings to the deprecated code.

Used warn_about_implementation() for ModelAdmin deprecation warnings on
get_list_select_related() return value and missing action_location
parameters in get_actions() and get_action_choices(). Fixes a problem
where the warnings would point to wsgiref rather than the ModelAdmin
subclass using deprecated functionality.

comment:14 by Jacob Walls <jacobtylerwalls@…>, 2 days ago

In 3143a7e:

[6.1.x] Refs #37187 -- Implemented warn_about_implementation() deprecation utility.

Created warn_about_implementation() for issuing warnings about
particular code that isn't currently on the call stack.

Backport of 260d136920acf27dbd3cae9bc80eba2a43b44bba from main.

comment:15 by Jacob Walls <jacobtylerwalls@…>, 2 days ago

In bc529fb8:

[6.1.x] Fixed #37187, #37190 -- Pointed ModelAdmin warnings to the deprecated code.

Used warn_about_implementation() for ModelAdmin deprecation warnings on
get_list_select_related() return value and missing action_location
parameters in get_actions() and get_action_choices(). Fixes a problem
where the warnings would point to wsgiref rather than the ModelAdmin
subclass using deprecated functionality.

Backport of 2e48636c54910e435eb31e1b7d8a8089c84233ad from main.

Note: See TracTickets for help on using tickets.
Back to Top