{{{
System check identified no issues (0 silenced).
April 10, 2023 - 19:04:29
Django version 5.0.dev20230410064954, using settings
'projectfromrepo.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
}}}
and visiting the admin site for the relevant model results in the
following error:
{{{
TypeError:
create_reverse_many_to_one_manager.<locals>.RelatedManager.__call__()
missing 1 required keyword-only argument: 'manager'
[10/Apr/2023 19:30:40] "GET /admin/testapp/question/ HTTP/1.1" 500 415926
}}}
Ideally, using a reversed foreign key would also result in a system check
error instead of a 500 response.
To reproduce, follow the `Question` and `Choice` models from the Django
Tutorial and add the following to the `QuestionAdmin`:
{{{
list_display = ["question_text", "choice_set"]
}}}
Then, visit `/admin/testapp/question/` and the following traceback is
returned:
{{{
Internal Server Error: /admin/testapp/question/
Traceback (most recent call last):
File "/some/path/django/django/db/models/options.py", line 681, in
get_field
return self.fields_map[field_name]
~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'choice_set'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/some/path/django/django/contrib/admin/utils.py", line 288, in
lookup_field
f = _get_non_gfk_field(opts, name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/contrib/admin/utils.py", line 319, in
_get_non_gfk_field
field = opts.get_field(name)
^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/db/models/options.py", line 683, in
get_field
raise FieldDoesNotExist(
django.core.exceptions.FieldDoesNotExist: Question has no field named
'choice_set'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/some/path/django/django/core/handlers/exception.py", line 55, in
inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/core/handlers/base.py", line 220, in
_get_response
response = response.render()
^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/response.py", line 111, in
render
self.content = self.rendered_content
^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/response.py", line 89, in
rendered_content
return template.render(context, self._request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/backends/django.py", line 61, in
render
return self.template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 171, in render
return self._render(context)
^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 163, in _render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in render
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in
<listcomp>
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 962, in
render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/loader_tags.py", line 157, in
render
return compiled_parent._render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 163, in _render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in render
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in
<listcomp>
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 962, in
render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/loader_tags.py", line 157, in
render
return compiled_parent._render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 163, in _render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in render
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in
<listcomp>
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 962, in
render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/loader_tags.py", line 63, in
render
result = block.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in render
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in
<listcomp>
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 962, in
render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/loader_tags.py", line 63, in
render
result = block.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in render
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 1001, in
<listcomp>
return SafeString("".join([node.render_annotated(context) for node in
self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/base.py", line 962, in
render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/contrib/admin/templatetags/base.py", line
45, in render
return super().render(context)
^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/template/library.py", line 258, in render
_dict = self.func(*resolved_args, **resolved_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/some/path/django/django/contrib/admin/templatetags/admin_list.py", line
340, in result_list
"results": list(results(cl)),
^^^^^^^^^^^^^^^^^
File
"/some/path/django/django/contrib/admin/templatetags/admin_list.py", line
316, in results
yield ResultList(None, items_for_result(cl, res, None))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File
"/some/path/django/django/contrib/admin/templatetags/admin_list.py", line
307, in __init__
super().__init__(*items)
File
"/some/path/django/django/contrib/admin/templatetags/admin_list.py", line
217, in items_for_result
f, attr, value = lookup_field(field_name, result, cl.model_admin)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/some/path/django/django/contrib/admin/utils.py", line 301, in
lookup_field
value = attr()
^^^^^^
TypeError:
create_reverse_many_to_one_manager.<locals>.RelatedManager.__call__()
missing 1 required keyword-only argument: 'manager'
[10/Apr/2023 19:30:40] "GET /admin/testapp/question/ HTTP/1.1" 500 415926
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34481>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* type: Uncategorized => Bug
* component: Uncategorized => contrib.admin
* stage: Unreviewed => Accepted
Comment:
Thanks for the report.
--
Ticket URL: <https://code.djangoproject.com/ticket/34481#comment:1>
* cc: Bakdolot (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/34481#comment:2>
* owner: nobody => Bakdolot
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/34481#comment:3>
Comment (by Bakdolot):
[https://github.com/django/django/pull/16531 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/34481#comment:4>
* has_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/34481#comment:5>
* needs_better_patch: 0 => 1
* needs_docs: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/34481#comment:6>
* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin
* needs_docs: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/34481#comment:7>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"c813fb327cb1b09542be89c5ceed367826236bc2" c813fb3]:
{{{
#!CommitTicketReference repository=""
revision="c813fb327cb1b09542be89c5ceed367826236bc2"
Fixed #34481 -- Added system check for reverse related fields in
ModelAdmin.list_display.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34481#comment:8>