Django inline link to model editing
I know this issue has been asked more than once, but as Django is evolving with new version, I'll ask the question again :
I am using the model User (Django User, not in my models.py) and create another model with a Foreign key to User.
models.py
:
class Plan(models.Model):
user = models.ForeignKey(User)
I can simply display every Plan
in my user by doing this in admin.py
:
class PlanInline(admin.TabularInline):
model = Plan
extra = 0
class MyUserAdmin(UserAdmin):
ordering = ('-date_joined', 'username')
inlines = [PlanInline,]
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
But things are about to get more tricky. I want to add a model that has a foreign key pointing to Plan
:
class Order(models.Model):
plan = models.ForeignKey('Plan')
And I want to be able to see all Orders
for each Plan
. As of today, it is impossible to have nested inlines in Django Admin (without editing the HTML, which I want to avoid) :
User
-> Plan 1
-> Order 1
-> Order 2
-> Plan 2
-> Order 3
So my idea is to display in the User Admin
only A LINK for each plan, to the page to edit Plans
, and put Orders
as inline :
class OrderInline(admin.TabularInline):
model = Order
extra = 0
class PlanAdmin(admin.ModelAdmin):
inlines = [OrderInline,]
admin.site.register(Plan, PlanAdmin)
The question is, how do I display a link to a Plan in my User Admin?
class MyUserAdmin(UserAdmin):
ordering = ('-date_joined', 'username')
??? LINK ????
I saw some solutions on this topic : Django InlineModelAdmin: Show partially an inline model and link to the complete model, but they are a bit "dirty' as they make us write HTML and absolute path into the code.
Then I saw this ticket on Djangoproject : https://code.djangoproject.com/ticket/13163. It seems exactly what I'm looking for, and the ticket is "fixed". So I tried adding like in the fix show_change_link = True
:
class PlanInline(admin.TabularInline):
model = Plan
extra = 0
show_change_link = True
class MyUserAdmin(UserAdmin):
ordering = ('-date_joined', 'username')
show_change_link = True
inlines = [UserProfileInline, PlanInline]
But it doesn't work (and I have no log or error).
Is there any way to do this in a clean way?
I suggest adding a custom PlanInline
method that returns the link and see if it helps. Something along these lines:
from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse
class PlanInline(TabularInline):
model = Plan
readonly_fields = ('change_link',)
...other options here...
def change_link(self, obj):
return mark_safe('<a href="%s">Full edit</a>' %
reverse('admin:myapp_plan_change',
args=(obj.id,)))
Basically all we do here is create the custom method that returns a link to the change page (this specific implementation is not tested, sorry if there is any parse error but you get the idea) and then add it to the readonly_fields as described here: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields
A couple of notes for the change_link
method: You need to replace 'myapp' in the view name with your actual application name. The mark_safe
method just marks the text as safe for the template engine to render it as html.
Update for django 1.8
show_change_link = True
https://github.com/django/django/pull/2957/files
链接地址: http://www.djcxy.com/p/65430.html上一篇: Django:创建类似于django admin的内联表单
下一篇: Django内嵌链接到模型编辑