Django Admin嵌套内联

tun*_*nak 45 django django-models django-admin

我需要一个嵌套的django admin inline,我可以在下面的其他内联中包含日期字段内联.

我有以下型号:

class Person(models.Model):
     name = models.CharField(max_length=200)
     id_no = models.IntegerField()

class Certificate(models.Model):
     cerfificate_no = models.CharField(max_length=200)
     certificate_date = models.DateField(max_length=100)
     person = models.ForeignKey(Person)
     training = models.CharField(max_length=200)

class Training_Date(models.Model):
      date = models.DateField()
      certificate = models.ForeignKey(Certificate)
Run Code Online (Sandbox Code Playgroud)

以及以下管理员:

class CertificateInline(admin.StackedInline):
    model = Certificate

class PersonAdmin(admin.ModelAdmin):
     inlines = [CertificateInline,]
admin.site.register(Person,PersonAdmin)
Run Code Online (Sandbox Code Playgroud)

但我需要将Training_Date模型包含在内联中,这是证书管理员内联的一部分.

任何的想法 ?

Dan*_*air 34

最近在https://code.djangoproject.com/ticket/9025中有一些动作,但我不会屏住呼吸.

解决此问题的一种常见方法是通过为同一模型同时使用ModelAdmin和Inline来链接到第一个和第二个(或第二个和第三个)级别之间的管理员:

将CertificateDate作为内联提供给ModelAdmin的证书.为CertificateInline提供一个附加字段"Details",它是ModelAdmin更改表单的链接.

models.py:

from django.core import urlresolvers

class Certificate(models.Model):

    # ...

    def changeform_link(self):
        if self.id:
            # Replace "myapp" with the name of the app containing
            # your Certificate model:
            changeform_url = urlresolvers.reverse(
                'admin:myapp_certificate_change', args=(self.id,)
            )
            return u'<a href="%s" target="_blank">Details</a>' % changeform_url
        return u''
    changeform_link.allow_tags = True
    changeform_link.short_description = ''   # omit column header
Run Code Online (Sandbox Code Playgroud)

admin.py:

# Certificate change form has training dates as inline

class TrainingDateInline(admin.StackedInline):
    model = TrainingDate

class CertificateAdmin(admin.ModelAdmin):
    inlines = [TrainingDateInline,]
admin.site.register(Certificate ,CertificateAdmin)

# Person has Certificates inline but rather
# than nesting inlines (not possible), shows a link to
# its own ModelAdmin's change form, for accessing TrainingDates:

class CertificateLinkInline(admin.TabularInline):
    model = Certificate
    # Whichever fields you want: (I usually use only a couple
    # needed to identify the entry)
    fields = ('cerfificate_no', 'certificate_date', 'changeform_link')
    readonly_fields = ('changeform_link', )

class PersonAdmin(admin.ModelAdmin):
    inlines = [CertificateLinkInline,]
admin.site.register(Person, PersonAdmin)
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案.我想指出你可以将`changeform_link`放在`CertificateLinkInline`中.这可能是一个更好的地方,因为它是django-admin特定的.请注意,执行此操作时,应使用`instance.id`而不是`self.id`来访问模型的实例.请参阅https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields (9认同)
  • 看起来在 Django 2+ 上,你只需将 `show_change_link = True` 添加到你的 admin.TabularInline 类中,我认为只要你有一个常规的 admin.ModelAdmin ,它就会在内联中显示一个“更改”链接。 (2认同)

小智 18

更通用的解决方案

from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse
class EditLinkToInlineObject(object):
    def edit_link(self, instance):
        url = reverse('admin:%s_%s_change' % (
            instance._meta.app_label,  instance._meta.model_name),  args=[instance.pk] )
        if instance.pk:
            return mark_safe(u'<a href="{u}">edit</a>'.format(u=url))
        else:
            return ''

class MyModelInline(EditLinkToInlineObject, admin.TabularInline):
    model = MyModel
    readonly_fields = ('edit_link', )

class MySecondModelAdmin(admin.ModelAdmin):
    inlines = (MyModelInline, )

admin.site.register(MyModel)
admin.site.register(MySecondModel, MySecondModelAdmin)
Run Code Online (Sandbox Code Playgroud)


s-b*_*ock 12

pip install django-nested-inline
Run Code Online (Sandbox Code Playgroud)

这个包应该做你需要的.

  • 最新的 django 版本还不支持 **django-nested-inline**。但您可以考虑使用几乎相同的 https://github.com/theatlantic/django-nested-admin 。 (2认同)

Pau*_*ine 11

AFAIK,你不能在默认的Django管理员中拥有第二级内联.

Django管理员只是一个普通的Django应用程序,所以没有什么能阻止你实现第二级嵌套表单,但恕我直言,这将是一种复杂的设计实现.也许这就是没有规定的原因.


小智 6

更新的解决方案(2021 年 2 月)是使用show_change_link配置变量:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.show_change_link

这与上面解决方案中提出的 EditLinkToInlineObject 完全相同,但代码更少,并且可能经过 Django 开发人员的充分测试

您只需show_change_link=True在每个内联中定义


Ric*_*era 5

嵌套内联在以下位置提供:https : //github.com/BertrandBordage/django-super-inlines/

pip install django-super-inlines
Run Code Online (Sandbox Code Playgroud)


小智 5

使用django-nested-admin这是执行嵌套内联的最佳包。

首先,安装“django-nested-admin”

pip install django-nested-admin
Run Code Online (Sandbox Code Playgroud)

然后,将“nested_admin”添加到“settings.py”中的“INSTALLED_APPS ” :

# "settings.py"

INSTALLED_APPS = (
    # ...
    "nested_admin", # Here
)
Run Code Online (Sandbox Code Playgroud)

然后,将“path('_nested_ad...”添加到“urls.py”中的“ urlpatterns ” :

# "urls.py"

from django.urls import include, path

urlpatterns = [
    # ...
    path('_nested_admin/', include('nested_admin.urls')), # Here
]
Run Code Online (Sandbox Code Playgroud)

最后,在“admin.py”中使用Training_DateInline()”和“CertificateInline()”类扩展“NestedTabularInline” ,并使用“PersonAdmin()”类扩展“NestedModelAdmin” ,如下所示:

# "admin.py"

from .models import Training_Date, Certificate, Person
from nested_admin import NestedTabularInline, NestedModelAdmin

class Training_DateInline(NestedTabularInline):
    model = Training_Date

class CertificateInline(NestedTabularInline):
    model = Certificate
    inlines = [Training_DateInline]

@admin.register(Person)
class PersonAdmin(NestedModelAdmin):
    inlines = [CertificateInline]
Run Code Online (Sandbox Code Playgroud)