Opened 3 years ago
Closed 2 years 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 , 3 years ago
| Description: | modified (diff) |
|---|---|
| Owner: | changed from to |
| Status: | new β assigned |
comment:2 by , 3 years ago
comment:3 by , 3 years 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 , 3 years 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:7 by , 3 years 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 , 3 years 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 , 3 years 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 , 3 years 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 , 2 years ago
| Has patch: | set |
|---|---|
| Patch needs improvement: | set |
comment:13 by , 2 years ago
| Patch needs improvement: | unset |
|---|---|
| Triage Stage: | Accepted β Ready for checkin |
I think I will make a bug fix later if required