Django

Code

Ticket #11163 (reopened)

Opened 10 months ago

Last modified 4 months ago

admin ForeignKeyRawIdWidget contains incorrect link when used in change list view

Reported by: margieroginski@yahoo.com Assigned to: nobody
Milestone: Component: django.contrib.admin
Version: SVN Keywords: raw_id_fields
Cc: semente@taurinus.org Triage Stage: Accepted
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 1

Description (Last modified by ramiro)

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:

http://mysite.com/admin/taskmanager/task/

while the url from the edit form is like this:

http://mysite.com/admin/taskmanager/task/1

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

11163.patch.1 (2.3 kB) - added by akaihola on 07/03/09 06:20:24.
Patch against r11173: imitating what RelatedFieldWidgetWrapper? does
11163.patch.2 (9.0 kB) - added by akaihola on 07/03/09 07:08:29.
Fixed many-to-many fields and tests, too (still against r11173).

Change History

05/20/09 16:17:16 changed by ramiro

  • description changed.

(reformatted description)

05/20/09 16:39:54 changed by Alex

  • status changed from new to closed.
  • resolution set to invalid.

This is fixed as long as you use the include(admin.site.urls) method for setting up the admin.

05/20/09 18:55:25 changed by margieroginski@yahoo.com

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)

05/20/09 19:02:40 changed by Alex

  • status changed from closed to reopened.
  • resolution deleted.

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 ) 05/21/09 00:46:06 changed by anonymous

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.

05/21/09 00:47:06 changed by margieroginski@yahoo.com

Oops. That anonymous response above is from me, Margie ...

07/03/09 06:20:24 changed by akaihola

  • attachment 11163.patch.1 added.

Patch against r11173: imitating what RelatedFieldWidgetWrapper? does

07/03/09 07:08:29 changed by akaihola

  • attachment 11163.patch.2 added.

Fixed many-to-many fields and tests, too (still against r11173).

(in reply to: ↑ 5 ) 07/03/09 07:14:35 changed by akaihola

  • keywords set to raw_id_fields.
  • has_patch set to 1.
  • version changed from 1.0 to SVN.
  • component changed from Uncategorized to django.contrib.admin.

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.

07/03/09 07:19:29 changed by akaihola

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.

07/27/09 08:18:10 changed by Guilherme Gondim <semente@taurinus.org>

  • cc set to semente@taurinus.org.

08/06/09 17:43:24 changed by Alex

  • stage changed from Unreviewed to Accepted.

11/19/09 09:05:34 changed by mykhul@gmail.com

  • has_patch deleted.

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

11/20/09 07:43:39 changed by akaihola

  • needs_better_patch set to 1.
  • has_patch set to 1.

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.

11/30/09 04:31:09 changed by bcurtu

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)

Add/Change #11163 (admin ForeignKeyRawIdWidget contains incorrect link when used in change list view)




Change Properties
Action