web-dev-qa-db-ja.com

Django admin?のインラインアイテムの完全な変更フォームへのリンクを追加します。

オブジェクトの標準の管理者変更フォームと、ForeignKey関係の通常のStackedInlineフォームがあります。インラインアイテムには独自のインラインアイテムがあり、ネストできないため、各インラインアイテムを対応するフルサイズの変更フォームにリンクできるようにしたいと思います。

カスタムウィジェットからカスタムテンプレートまですべてを試しましたが、何も機能しません。これまでのところ、スニペットの形で見た「ソリューション」は、インラインでは機能しないようです。 jQueryを使ってDOMハッキングを試して、動作させて先に進む準備をしています。

これはとても単純な作業のように見えるので、私は非常に単純なものを見逃しているに違いないことを願っています!

Django 1.2を使用します。

38
David Eyk

私も同様の問題を抱えていて、カスタムウィジェットとモデルフォームの微調整を思いつきました。ウィジェットは次のとおりです。

from Django.utils.safestring import  mark_safe    

class ModelLinkWidget(forms.Widget):
    def __init__(self, obj, attrs=None):
        self.object = obj
        super(ModelLinkWidget, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        if self.object.pk:
            return mark_safe(
                u'<a target="_blank" href="../../../%s/%s/%s/">%s</a>' %\
                      (
                       self.object._meta.app_label,
                       self.object._meta.object_name.lower(),
                       self.object.pk, self.object
                       )
            )
        else:
            return mark_safe(u'')

これで、各インラインのウィジェットはコンストラクターで異なるオブジェクトを取得する必要があるため、標準的な方法で設定するだけでなく、フォームのinitメソッドで設定できます。

class TheForm(forms.ModelForm):
    ...
    # required=False is essential cause we don't
    # render input tag so there will be no value submitted.
    link = forms.CharField(label='link', required=False)

    def __init__(self, *args, **kwargs):
        super(TheForm, self).__init__(*args, **kwargs)
        # instance is always available, it just does or doesn't have pk.
        self.fields['link'].widget = ModelLinkWidget(self.instance)

それがお役に立てば幸いです。

11

Django 1.8なので、 show_change_link というプロパティがあります。

95
Florian

Admin.pyで次のようなことをしました。

from Django.utils.html import format_html
from Django.core.urlresolvers import reverse

class MyModelInline(admin.TabularInline):
    model = MyModel

    def admin_link(self, instance):
        url = reverse('admin:%s_%s_change' % (instance._meta.app_label,  
                                              instance._meta.module_name),
                      args=(instance.id,))
        return format_html(u'<a href="{}">Edit</a>', url)
        # … or if you want to include other fields:
        return format_html(u'<a href="{}">Edit: {}</a>', url, instance.title)

    readonly_fields = ('admin_link',)

ここで現在受け入れられている解決策は良い仕事ですが、時代遅れです。

Django 1.3なので、この問題に対処するshow_change_link = Trueという組み込みプロパティがあります。

これは、StackedInlineまたはTabularInlineオブジェクトに追加できます。例えば:

class ContactListInline(admin.TabularInline):
    model = ContactList
    fields = ('name', 'description', 'total_contacts',)
    readonly_fields = ('name', 'description', 'total_contacts',)
    show_change_link = True

結果は次のようになります。

tabular inline using show_change_link

13
Joe Davy

上記のQuentinの回答は機能しますが、fields =( 'admin_link'、)も指定する必要があります。

3
Patti

Args = [instance.id]はargs = [instance.pk]である必要があると思います。それは私のために働いた!

0
Andrey