Opened 19 months ago
Closed 19 months ago
#34513 closed Bug (fixed)
Error E108 does not cover some cases
Reported by: | Baha Sdtbekov | Owned by: | Baha Sdtbekov |
---|---|---|---|
Component: | contrib.admin | Version: | 4.2 |
Severity: | Normal | Keywords: | |
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 )
I have two models, Question
and Choice
. And if I write list_display = ["choice"]
in QuestionAdmin
, I get no errors.
But when I visit /admin/polls/question/
, the following trace is returned:
Internal Server Error: /admin/polls/question/ Traceback (most recent call last): File "/some/path/django/contrib/admin/utils.py", line 334, in label_for_field field = _get_non_gfk_field(model._meta, name) File "/some/path/django/contrib/admin/utils.py", line 310, in _get_non_gfk_field raise FieldDoesNotExist() django.core.exceptions.FieldDoesNotExist During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/some/path/django/core/handlers/exception.py", line 55, in inner response = get_response(request) File "/some/path/django/core/handlers/base.py", line 220, in _get_response response = response.render() File "/some/path/django/template/response.py", line 111, in render self.content = self.rendered_content File "/some/path/django/template/response.py", line 89, in rendered_content return template.render(context, self._request) File "/some/path/django/template/backends/django.py", line 61, in render return self.template.render(context) File "/some/path/django/template/base.py", line 175, in render return self._render(context) File "/some/path/django/template/base.py", line 167, in _render return self.nodelist.render(context) File "/some/path/django/template/base.py", line 1005, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 1005, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 966, in render_annotated return self.render(context) File "/some/path/django/template/loader_tags.py", line 157, in render return compiled_parent._render(context) File "/some/path/django/template/base.py", line 167, in _render return self.nodelist.render(context) File "/some/path/django/template/base.py", line 1005, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 1005, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 966, in render_annotated return self.render(context) File "/some/path/django/template/loader_tags.py", line 157, in render return compiled_parent._render(context) File "/some/path/django/template/base.py", line 167, in _render return self.nodelist.render(context) File "/some/path/django/template/base.py", line 1005, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 1005, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 966, in render_annotated return self.render(context) File "/some/path/django/template/loader_tags.py", line 63, in render result = block.nodelist.render(context) File "/some/path/django/template/base.py", line 1005, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 1005, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 966, in render_annotated return self.render(context) File "/some/path/django/template/loader_tags.py", line 63, in render result = block.nodelist.render(context) File "/some/path/django/template/base.py", line 1005, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 1005, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/some/path/django/template/base.py", line 966, in render_annotated return self.render(context) File "/some/path/django/contrib/admin/templatetags/base.py", line 45, in render return super().render(context) File "/some/path/django/template/library.py", line 258, in render _dict = self.func(*resolved_args, **resolved_kwargs) File "/some/path/django/contrib/admin/templatetags/admin_list.py", line 326, in result_list headers = list(result_headers(cl)) File "/some/path/django/contrib/admin/templatetags/admin_list.py", line 90, in result_headers text, attr = label_for_field( File "/some/path/django/contrib/admin/utils.py", line 362, in label_for_field raise AttributeError(message) AttributeError: Unable to lookup 'choice' on Question or QuestionAdmin [24/Apr/2023 15:43:32] "GET /admin/polls/question/ HTTP/1.1" 500 349913
I suggest that error E108 be updated to cover this case as well
For reproduce see βgithub
Change History (14)
comment:1 by , 19 months ago
Description: | modified (diff) |
---|---|
Owner: | changed from | to
Status: | new β assigned |
comment:2 by , 19 months ago
comment:3 by , 19 months ago
Triage Stage: | Unreviewed β Accepted |
---|
Thanks bakdolot π
There's a slight difference between a model instance's attributes and the model class' meta's fields. Meta stores the reverse relationship as choice
, where as this would be setup & named according to whatever the related_name is declared as.
comment:4 by , 19 months ago
fyi potential quick fix, this will cause it to start raising E108 errors.
this is just a demo of where to look. One possibility we could abandon using get_field()
and refer to _meta.fields
instead? π€β¦Β though that would mean the E109 check below this would no longer work.
-
django/contrib/admin/checks.py
a b from django.core.exceptions import FieldDoesNotExist 9 9 from django.db import models 10 10 from django.db.models.constants import LOOKUP_SEP 11 11 from django.db.models.expressions import Combinable 12 from django.db.models.fields.reverse_related import ManyToOneRel 12 13 from django.forms.models import BaseModelForm, BaseModelFormSet, _get_foreign_key 13 14 from django.template import engines 14 15 from django.template.backends.django import DjangoTemplates … … class ModelAdminChecks(BaseModelAdminChecks): 897 898 return [] 898 899 try: 899 900 field = obj.model._meta.get_field(item) 901 if isinstance(field, ManyToOneRel): 902 raise FieldDoesNotExist 900 903 except FieldDoesNotExist: 901 904 try: 902 905 field = getattr(obj.model, item)
comment:6 by , 19 months ago
@nessita yup I recognised bakdolot's user username from that patch :D
comment:7 by , 19 months ago
Oh no they recognized me :D
I apologize very much. I noticed this bug only after merge when I decided to check again
By the way, I also noticed two bugs related to this
follow-up: 9 comment:8 by , 19 months ago
I checked most of the fields and found these fields that are not working correctly
class QuestionAdmin(admin.ModelAdmin): list_display = ["choice", "choice_set", "somem2m", "SomeM2M_question+", "somem2m_set", "__module__", "__doc__", "objects"]
Also for reproduce see βgithub
comment:9 by , 19 months ago
Replying to Baha Sdtbekov:
I checked most of the fields and found these fields that are not working correctly
class QuestionAdmin(admin.ModelAdmin): list_display = ["choice", "choice_set", "somem2m", "SomeM2M_question+", "somem2m_set", "__module__", "__doc__", "objects"]Also for reproduce see βgithub
System checks are helpers that in this case should highlight potentially reasonable but unsupported options. IMO they don't have to catch all obviously wrong values that you can find in __dir__
.
comment:10 by , 19 months ago
Yup agreed with felixx if they're putting __doc__
in there then they probably need to go back and do a Python tutorial :)
As for choice_set
& somem2m
β I thought that's what you fixed up in the other patch with E109.
comment:12 by , 19 months ago
Has patch: | set |
---|---|
Patch needs improvement: | set |
comment:13 by , 19 months ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted β Ready for checkin |
I think I will make a bug fix later if required