Django内联链接编辑模型
我知道这个问题已经被问过很多次了,但随着Django版本的更新,我想再问一次:
我正在使用Django自带的用户模型User(不是我自己在models.py里定义的),并且创建了一个新的模型,这个模型通过外键关联到User。
models.py
:
class Plan(models.Model):
user = models.ForeignKey(User)
我可以在admin.py
里简单地显示每个用户的Plan
,方法如下:
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)
但事情变得有点复杂了。我想添加一个模型,这个模型的外键指向Plan
:
class Order(models.Model):
plan = models.ForeignKey('Plan')
我希望能看到每个Plan
的所有Orders
。目前,在Django Admin中,无法实现嵌套的内联显示(除非修改HTML,但我不想这样做):
User
-> Plan 1
-> Order 1
-> Order 2
-> Plan 2
-> Order 3
所以我的想法是在User Admin
中只显示每个计划的一个链接,指向编辑Plans
的页面,并将Orders
作为内联显示:
class OrderInline(admin.TabularInline):
model = Order
extra = 0
class PlanAdmin(admin.ModelAdmin):
inlines = [OrderInline,]
admin.site.register(Plan, PlanAdmin)
我的问题是,如何在用户管理界面中显示指向Plan的链接呢?
class MyUserAdmin(UserAdmin):
ordering = ('-date_joined', 'username')
??? LINK ????
我看到了一些关于这个话题的解决方案:Django InlineModelAdmin: Show partially an inline model and link to the complete model,但是这些方案有点“麻烦”,因为它们要求我们在代码中写HTML和绝对路径。
然后我在Django项目上看到这个问题单:https://code.djangoproject.com/ticket/13163。这似乎正是我想要的,而且这个问题单已经“修复”了。所以我尝试像修复中那样添加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]
但这并没有奏效(而且我没有任何日志或错误信息)。
有没有什么办法可以以一种干净的方式做到这一点呢?
2 个回答
我建议你添加一个自定义的 PlanInline
方法,让它返回一个链接,看看这样是否有帮助。大致可以这样做:
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,)))
其实我们在这里做的就是创建一个自定义方法,这个方法返回一个指向修改页面的链接(这个具体的实现没有经过测试,如果有解析错误请见谅,但你应该能明白我的意思),然后把它添加到只读字段中,具体可以参考这里的说明:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields
关于 change_link
方法,有几点需要注意:你需要把视图名称中的 'myapp' 替换成你实际的应用名称。mark_safe
方法的作用是告诉模板引擎,这段文本是安全的,可以直接渲染成 HTML。