【问题标题】:Django inline link to model editing模型编辑的 Django 内联链接
【发布时间】:2014-09-27 00:24:29
【问题描述】:

我知道这个问题已经被问过不止一次了,但是随着 Django 的新版本的发展,我会再次问这个问题:

我正在使用模型 User(Django 用户,不在我的 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)

问题是,如何在我的用户管理中显示指向计划的链接?

class MyUserAdmin(UserAdmin):
    ordering = ('-date_joined', 'username')
    ??? LINK ????

我看到了一些关于这个主题的解决方案:Django InlineModelAdmin: Show partially an inline model and link to the complete model,但它们有点“脏”,因为它们让我们在代码中写入 HTML 和绝对路径。

然后我在 Djangoproject 上看到了这张票: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]

但它不起作用(而且我没有日志或错误)。

有什么方法可以干净利落地做到这一点吗?

【问题讨论】:

  • 我不确定该票是否符合您的描述,但无论如何它仅在四天前关闭。您是否正在与 Django 存储库的 HEAD 竞争?
  • "你是否在运行 Django 存储库的 HEAD?"对不起,我不明白(不是以英语为母语的人)。是的,既然你指出了这一点,我想修复是针对 1.7 或者我的 Django 不是最新的修复。

标签: python django django-models django-admin


【解决方案1】:

django 1.8 更新

show_change_link = True

https://github.com/django/django/pull/2957/files

【讨论】:

  • 这应该是正确的答案了。
【解决方案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,)))

基本上我们在这里所做的就是创建返回更改页面链接的自定义方法(这个特定的实现没有经过测试,如果有任何解析错误很抱歉,但你明白了),然后将它添加到 readonly_fields 为此处描述:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields

change_link 方法的一些注意事项:您需要将视图名称中的“myapp”替换为您的实际应用程序名称。 mark_safe 方法只是将文本标记为安全,以便模板引擎将其呈现为 html。

【讨论】:

  • 是的,这就是我们所寻求的解决方案,因为似乎还没有其他方法(这个答案的一个变体:*.com/a/21079750/3768672