2013-01-13 11 views
28

ネストされたdjango管理者インライン が必要です。以下のように、日付フィールドのインラインを他のインラインに含めることができます。Django Adminネストされたインライン

私は以下のモデルがあります:

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) 

と以下の管理:

class CertificateInline(admin.StackedInline): 
    model = Certificate 

class PersonAdmin(admin.ModelAdmin): 
    inlines = [CertificateInline,] 
admin.site.register(Person,PersonAdmin) 

をしかし、私は、証明書管理、インラインの一部であるインラインとしてTraining_Dateモデルを含める必要があります。

答えて

9

AFAIKでは、デフォルトのDjango管理者に2番目のレベルのインラインを設定することはできません。

Djangoの管理者は通常のDjangoアプリケーションですので、2番目のレベルのネストされたフォームを実装することはできませんが、IMHOは実装するための一種の複雑なデザインです。おそらくそれがそれのための準備がない理由です。

+0

を私は同様のシナリオに直面しています。私は、インラインテンプレートをオーバーライドして、2番目のレベルにいくつかのリンクを追加するつもりだと思います。 – Damon

31

最近、https://code.djangoproject.com/ticket/9025に動きがありますが、私は息を止めません。

この周りの一つの一般的な方法は、同じモデルのModelAdminのとインラインの両方を有することにより、第1及び第2(または第二及び第三の)レベルと管理者にリンクすることである。

として証明書をTrainingDateとModelAdminのを与えインラインCertificateInlineに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 

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) 
+8

これは素晴らしい解決策です。私はあなたが 'CertificateLinkInline'に' changeform_link'を置くことができることを指摘したいと思います。これはdjango-admin特有のものなので、より良い場所になるかもしれません。これを行うときは、モデルのインスタンスに到達するために 'self.id'の代わりに' instance.id'を使うべきです。 https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields – rednaw

+0

を参照してください。changeform_linkメソッドが例外を生成すると、djangoはそれを食べて続け、フィールドを残しますブランク。私はDjangoがトレースバックを置く場所を見つけることができませんでした。 try/exceptでラップして例外がどこかに記録されるようにすることをお勧めします。単純化するために、このすべてをデコレータハンドルで作成すると便利です。 –

9

もっとユニバーサルソリューション

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) 
+0

シンプルでフレキシブル。 +1 – yekta

8
pip install django-nested-inline 

このパッケージには、あなたが必要なものを行う必要があります。私は(ありがとう)@bigzbigが提供するソリューションを使用 https://github.com/BertrandBordage/django-super-inlines/

pip install django-super-inlines 
+0

** django-nested-inline **は最新のdjangoリリースではサポートされていません。 しかし、ほぼ同じhttps://github.com/theatlantic/django-nested-adminの使用を検討することもできます。 – vmonteco

+0

@vmontecoあなたは私にドキュメンテーションへのリンクを与えることができますか?パッケージなしでそれを使う方法が記述されていますか? –

+1

@OleksandrDashkov http://django-nested-admin.readthedocs.io/en/latest/、githubページの上部にあります。しかし、おそらくまだとにかくパッケージをインストールする必要があります。 – vmonteco

2

ネストされたインラインが設けられています。私はまた、変更が保存されていた後に戻って最初のリストページに行きたかった

はこれを追加しました:

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

    def response_post_save_change(self, request, obj): 
     my_second_model_id = MyModel.objects.get(pk=obj.pk).my_second_model_id 
     return redirect("/admin/mysite/mysecondmodel/%s/change/" % (my_second_model_id)) 
+0

私はそれを試した。インラインの一部を追加または削除したり、3つの新しい子オブジェクトを作成したりすることはできません。これは開発のこの段階では使用できません。 – max

0

関連する問題