Opened 14 years ago
Closed 14 years ago
#14283 closed (duplicate)
AttributeError on admin detail page after r13708
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Contrib apps | Version: | 1.2 |
Severity: | Keywords: | ||
Cc: | Simon Litchfield, rokclimb15@…, django@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
After updating to the latest Django version (r13840), I am getting strange errors when displaying the admin detail page for some of my models. I haven't touched my own admin or model classes for a while, so I suspect this could be a bug in a recent Django changeset. I am not very familiar with this part of Django, but it seems like the request object is not passed through correctly.
Here is the traceback:
Traceback (most recent call last): File "/usr/local/python-2.6/lib/python2.6/site-packages/django/core/handlers/base.py", line 100, in get_response response = callback(request, *callback_args, **callback_kwargs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/contrib/admin/options.py", line 245, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/utils/decorators.py", line 76, in _wrapped_view response = view_func(request, *args, **kwargs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/views/decorators/cache.py", line 69, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/contrib/admin/sites.py", line 190, in inner return view(request, *args, **kwargs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/utils/decorators.py", line 21, in _wrapper return decorator(bound_func)(*args, **kwargs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/utils/decorators.py", line 76, in _wrapped_view response = view_func(request, *args, **kwargs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/utils/decorators.py", line 17, in bound_func return func(self, *args2, **kwargs2) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/db/transaction.py", line 299, in _commit_on_success res = func(*args, **kw) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/contrib/admin/options.py", line 913, in change_view for FormSet, inline in zip(self.get_formsets(request, obj), self.inline_instances): File "/usr/local/python-2.6/lib/python2.6/site-packages/django/contrib/admin/options.py", line 421, in get_formsets yield inline.get_formset(request, obj) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/contrib/contenttypes/generic.py", line 403, in get_formset return generic_inlineformset_factory(self.model, **defaults) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/contrib/contenttypes/generic.py", line 369, in generic_inlineformset_factory fields=fields, exclude=exclude, max_num=max_num) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/forms/models.py", line 685, in modelformset_factory formfield_callback=formfield_callback) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/forms/models.py", line 423, in modelform_factory return ModelFormMetaclass(class_name, (form,), form_class_attrs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/forms/models.py", line 227, in __new__ opts.exclude, opts.widgets, formfield_callback) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/forms/models.py", line 185, in fields_for_model formfield = formfield_callback(f, **kwargs) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/contrib/admin/options.py", line 113, in formfield_for_dbfield related_modeladmin.has_add_permission(request)) File "/usr/local/python-2.6/lib/python2.6/site-packages/django/contrib/admin/options.py", line 292, in has_add_permission return request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) AttributeError: 'NoneType' object has no attribute 'user'
Looking through the recent changes in Django trunk, I see that r13731 changed fields_for_model in django.forms.models, which is also in the traceback. Could this have something to do with it?
For reference, here is my model admin class:
class EventAdmin(dj_admin.ModelAdmin): model = my_models.Event inlines = [metadata_admin.CommentInline, metadata_admin.RatingInline, metadata_admin.TagInline] date_hierarchy = 'created' raw_id_fields = ['owner', 'image', 'address'] list_display = ['title', 'owner', 'created', 'is_active', 'is_hidden', 'community'] list_filter = ['is_highlighted', 'community'] fieldsets = [ (None, {'fields': ['owner', 'community', ('start', 'end'), 'title', 'description', 'address', 'image', ('is_hidden', 'is_active'), 'is_highlighted', 'license']}), (u'Statistiken', {'fields': ['views', 'num_comments', 'num_ratings', 'average_rating'], 'classes': ['collapse']}) ] save_on_top = True search_fields = ['title']
Attachments (2)
Change History (14)
comment:1 by , 14 years ago
Summary: | AttributeError: 'NoneType' object has no attribute 'user' on admin detail page → AttributeError on admin detail page after r13708 |
---|
comment:2 by , 14 years ago
I have spent some more time tracking down this problem. Here is what I have found out.
There are three model classes involved:
- Model A, no fields required
- Model B, no fields required
- Model C, with a generic foreign key and a regular foreign key to model B
And there are also two admin classes involved:
- ModelCInline, a GenericTabularInline for model C
- ModelAAdmin, which includes ModelCInline
- In addition, model B must be registered with the admin site, but does not need any special options
When I try to add or change instances of model A on the admin site, I get an AttributeError with the following traceback:
Environment: Request Method: GET Request URL: http://localhost:8000/admin/testapp/modela/add/ Django Version: 1.3 pre-alpha SVN-13865 Python Version: 2.7.0 Installed Applications: ['django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.admin', 'testcase14283.testapp'] Installed Middleware: ('django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware') Traceback: File "/Users/rpuls/Library/Python/django/core/handlers/base.py" in get_response 100. response = callback(request, *callback_args, **callback_kwargs) File "/Users/rpuls/Library/Python/django/contrib/admin/options.py" in wrapper 245. return self.admin_site.admin_view(view)(*args, **kwargs) File "/Users/rpuls/Library/Python/django/utils/decorators.py" in _wrapped_view 76. response = view_func(request, *args, **kwargs) File "/Users/rpuls/Library/Python/django/views/decorators/cache.py" in _wrapped_view_func 78. response = view_func(request, *args, **kwargs) File "/Users/rpuls/Library/Python/django/contrib/admin/sites.py" in inner 190. return view(request, *args, **kwargs) File "/Users/rpuls/Library/Python/django/utils/decorators.py" in _wrapper 21. return decorator(bound_func)(*args, **kwargs) File "/Users/rpuls/Library/Python/django/utils/decorators.py" in _wrapped_view 76. response = view_func(request, *args, **kwargs) File "/Users/rpuls/Library/Python/django/utils/decorators.py" in bound_func 17. return func(self, *args2, **kwargs2) File "/Users/rpuls/Library/Python/django/db/transaction.py" in _commit_on_success 299. res = func(*args, **kw) File "/Users/rpuls/Library/Python/django/contrib/admin/options.py" in add_view 822. self.inline_instances): File "/Users/rpuls/Library/Python/django/contrib/admin/options.py" in get_formsets 421. yield inline.get_formset(request, obj) File "/Users/rpuls/Library/Python/django/contrib/contenttypes/generic.py" in get_formset 403. return generic_inlineformset_factory(self.model, **defaults) File "/Users/rpuls/Library/Python/django/contrib/contenttypes/generic.py" in generic_inlineformset_factory 369. fields=fields, exclude=exclude, max_num=max_num) File "/Users/rpuls/Library/Python/django/forms/models.py" in modelformset_factory 685. formfield_callback=formfield_callback) File "/Users/rpuls/Library/Python/django/forms/models.py" in modelform_factory 423. return ModelFormMetaclass(class_name, (form,), form_class_attrs) File "/Users/rpuls/Library/Python/django/forms/models.py" in __new__ 227. opts.exclude, opts.widgets, formfield_callback) File "/Users/rpuls/Library/Python/django/forms/models.py" in fields_for_model 185. formfield = formfield_callback(f, **kwargs) File "/Users/rpuls/Library/Python/django/contrib/admin/options.py" in formfield_for_dbfield 113. related_modeladmin.has_add_permission(request)) File "/Users/rpuls/Library/Python/django/contrib/admin/options.py" in has_add_permission 292. return request.user.has_perm(opts.app_label + '.' + opts.get_add_permission()) Exception Type: AttributeError at /admin/testapp/modela/add/ Exception Value: 'NoneType' object has no attribute 'user'
One interesting thing is that the error goes away as soon as I remove the line that registers model B with the admin site.
For a minimal test case, you can use the attached project, which is basically just a models.py:
import django.db.models as dj_models import django.contrib.admin as dj_admin import django.contrib.contenttypes.models as dj_ct_models import django.contrib.contenttypes.generic as dj_generic # model classes class ModelC(dj_models.Model): relation_b = dj_models.ForeignKey('ModelB') tagged_object = dj_generic.GenericForeignKey() content_type = dj_models.ForeignKey(dj_ct_models.ContentType) object_id = dj_models.PositiveIntegerField() class ModelA(dj_models.Model): pass class ModelB(dj_models.Model): pass # admin classes class ModelCInline(dj_generic.GenericTabularInline): model = ModelC class ModelAAdmin(dj_admin.ModelAdmin): inlines = [ModelCInline] dj_admin.site.register(ModelA, ModelAAdmin) # remove the following line to make the error go away dj_admin.site.register(ModelB)
comment:3 by , 14 years ago
Has patch: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
Need to curry formfield_for_dbfield in contenttypes/generic.py. Patch attached.
by , 14 years ago
Attachment: | fix14283.patch added |
---|
comment:4 by , 14 years ago
Component: | Uncategorized → Contrib apps |
---|
comment:5 by , 14 years ago
Cc: | added |
---|
Same error, same stacktrace exactly.
This time with an inline that has two keys back to the "parent" model and uses "fk_name" to select which one to link by.
So, this isn't just a GenericForeignKey issue. Somehow, formfield_for_dbfield() is getting a None request object in other instances also (haven't dug any deeper just yet).
comment:6 by , 14 years ago
Has patch: | unset |
---|---|
Patch needs improvement: | set |
Triage Stage: | Accepted → Unreviewed |
comment:7 by , 14 years ago
Has patch: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
@simon29: there was no need to reset the status to "Unreviewed". The ticket is still accepted. Also, there is still a patch, even if it needs improvement, so unchecking the "has patch" box is also unnecessary.
If you're still seeing failures after applying the latest patch, the best thing to do is to provide a failing unit test. Thanks!
comment:9 by , 14 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:10 by , 14 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
comment:11 by , 14 years ago
Cc: | added |
---|
comment:12 by , 14 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
This actually seems to be caused by r13708. When I revert this changeset, the detail page appears normally again.