Opened 15 years ago
Closed 14 years ago
#11163 closed (duplicate)
admin ForeignKeyRawIdWidget contains incorrect link when used in change list view
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | contrib.admin | Version: | dev |
Severity: | Keywords: | raw_id_fields | |
Cc: | semente@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
When the user specifies in their admin.py that a field is both editable and a raw_id, like this:
list_editable = ('owner',) raw_id_fields = ('owner',)
the ForeignKeyRawIdWidget is used in the change list view for that field. However, the code in the ForeignKeyRawIdWidget's render() method is hardcoded to be called from the edit form, with the following code:
related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower())
When called from the change list, the url has one less entry than when called from the edit form. As a result, the link is wrong when called from the change list. For example, the url for the changelist is something like this:
while the url from the edit form is like this:
So when used in the change list, the raw id widget's link ends up pointing to http://mysite.com/auth/user/?t=id rather than http://mysite.com/admin/auth/user/?t=id
Attachments (2)
Change History (17)
comment:1 by , 15 years ago
Description: | modified (diff) |
---|
comment:2 by , 15 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
This is fixed as long as you use the include(admin.site.urls) method for setting up the admin.
comment:3 by , 15 years ago
I am including admin.site.urls. My urls.py looks like this:
from django.contrib import admin
admin.autodiscover()
import os
urlpatterns = patterns(,
(r'admin/', include(admin.site.urls)),
)
if settings.SERVE_MEDIA:
urlpatterns += patterns(,
(r'site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': os.path.join(os.path.dirname(file), "site_media")}),
)
I don't know if this is useful, but here is the value that site.get_urls() returns (newlines added by me):
(Pdb) from django.contrib.admin.sites import site
(Pdb) site
<django.contrib.admin.sites.AdminSite object at 0x2a9a5bf2d0>
(Pdb) site.get_urls()
[<RegexURLPattern admin_index $>,
<RegexURLPattern %sadmin_logout logout/$>,
<RegexURLPattern admin_password_change password_change/$>,
<RegexURLPattern admin_password_change_done password_change/done/$>,
<RegexURLPattern admin_jsi18n jsi18n/$>,
<RegexURLPattern None r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$>,
<RegexURLPattern admin_app_list (?P<app_label>\w+)/$>,
<RegexURLResolver [<RegexURLPattern admin_auth_group_changelist $>,
<RegexURLPattern admin_auth_group_add add/$>,
<RegexURLPattern admin_auth_group_history (.+)/history/$>,
<RegexURLPattern admin_auth_group_delete (.+)/delete/$>,
<RegexURLPattern admin_auth_group_change (.+)/$>] auth/group/>,
<RegexURLResolver [<RegexURLPattern None (\d+)/password/$>,
<RegexURLPattern admin_auth_user_changelist $>,
<RegexURLPattern admin_auth_user_add add/$>,
<RegexURLPattern admin_auth_user_history (.+)/history/$>,
<RegexURLPattern admin_auth_user_delete (.+)/delete/$>,
<RegexURLPattern admin_auth_user_change (.+)/$>] auth/user/>,
<RegexURLResolver [<RegexURLPattern admin_sites_site_changelist $>,
<RegexURLPattern admin_sites_site_add add/$>,
<RegexURLPattern admin_sites_site_history (.+)/history/$>,
<RegexURLPattern admin_sites_site_delete (.+)/delete/$>,
<RegexURLPattern admin_sites_site_change (.+)/$>] sites/site/>,
<RegexURLResolver [<RegexURLPattern admin_taskmanager_task_changelist $>,
<RegexURLPattern admin_taskmanager_task_add add/$>,
<RegexURLPattern admin_taskmanager_task_history (.+)/history/$>,
<RegexURLPattern admin_taskmanager_task_delete (.+)/delete/$>,
<RegexURLPattern admin_taskmanager_task_change (.+)/$>] taskmanager/task/>]
(Pdb)
comment:4 by , 15 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
Reopening because I may have confused this with the bug fixed in r10235, I'll reclose if it turns out I was indeed correct.
follow-up: 7 comment:5 by , 15 years ago
I think this needs a similar fix to the one made for r10235 (but in ForeignKeyRawIdWidget). I think a similar fix may also be needed in RelatedFieldWidgetWraper, where there is another hardcoded url
related_url = '../../../%s/%s/' % (rel_to._meta.app_label, rel_to._meta.object_name.lower())
Sorry I can't jump in and fix it. I am overloaded with my own work right now, but as I get more familiar with the source and how to do patches, I will hopefully get to the point where I can.
by , 15 years ago
Attachment: | 11163.patch.1 added |
---|
Patch against r11173: imitating what RelatedFieldWidgetWrapper does
by , 15 years ago
Attachment: | 11163.patch.2 added |
---|
Fixed many-to-many fields and tests, too (still against r11173).
comment:7 by , 15 years ago
Component: | Uncategorized → django.contrib.admin |
---|---|
Has patch: | set |
Keywords: | raw_id_fields added |
Version: | 1.0 → SVN |
Replying to margieroginski@yahoo.com:
I think this needs a similar fix to the one made for r10235 (but in ForeignKeyRawIdWidget). I think a similar fix may also be needed in RelatedFieldWidgetWraper, where there is another hardcoded url
related_url = '../../../%s/%s/' % (rel_to._meta.app_label, rel_to._meta.object_name.lower())
That looks like a fallback when reverse URL resolution fails. I tried my patch without that fallback in ForeignKeyRawIdWidget
and all tests were good. I didn't try the same for RelatedFieldWidgetWrapper
though.
comment:8 by , 15 years ago
My patch is backwards-incompatible for anyone using ForeignKeyRawIdWidget
or ManyToManyRawIdWidget
directly. That could be fixed by defaulting admin_site=None
and falling back to old behavior if the caller omits admin_site
. On the other hand, that would make the code unnecessarily messy.
comment:9 by , 15 years ago
Cc: | added |
---|
comment:10 by , 15 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:11 by , 15 years ago
Has patch: | unset |
---|
I am experiencing this problem on the latest trunk 1.2 pre-alpha SVN-11731
What can I do?
I was told to:
Replace the ForeignKeyRawIdWidget for your changelist formset's forms.
..what does this mean? is this the right fix? i'm completely confused
comment:12 by , 15 years ago
Has patch: | set |
---|---|
Patch needs improvement: | set |
Looks like my patch is incompatible with Russell's changeset for named URL namespacing ([11250]). Unfortunately I can't dig deeper into this right now, but I hope to do it soon.
comment:13 by , 15 years ago
I have tried this solution, I think it works. Just add the name of the admin view to reverse:
related_url = reverse('admin:%s_%s_changelist' % info, current_app=self.admin_site.name)
comment:14 by , 14 years ago
Caution about the reverse method, if the model that the foreignkey does not exist in the current admin (possibly registered in a different admin for instance) then it will raise an error. If this error occurs we should catch it and not render the magnifying glass or fallback to original functionality. Aside from that the url reverse solution I like the most.
comment:15 by , 14 years ago
Resolution: | → duplicate |
---|---|
Status: | reopened → closed |
(reformatted description)