12

モデルは次のように設定されています。

class ParentModel(models.Model):
    some_col = models.IntegerField()
    some_other = models.CharField()

class ChildModel(models.Model)
    parent = models.ForeignKey(ParentModel, related_name='children')

class ToyModel(models.Model)
    child_owner = models.ForeignKey(ChildModel, related_name='toys')

管理パネルでチェンジリストを開いたときにParentModel、list_displayの新しいフィールド/列に、のチェンジリストを開くためのリンクがありますがChildModel、選択した親の子のみを表示するフィルターが適用されています。今のところ私はこの方法でそれを実現しました、しかし私はそれをするよりきれいな方法があると思います、私はただ方法がわかりません:

class ParentAdmin(admin.ModelAdmin)
    list_display = ('id', 'some_col', 'some_other', 'list_children')
    def list_children(self, obj):
        url = urlresolvers.reverse('admin:appname_childmodel_changelist')
        return '<a href="{0}?parent__id__exact={1}">List children</a>'.format(url, obj.id)
    list_children.allow_tags = True
    list_children.short_description = 'Children'        

admin.site.register(Parent, ParentAdmin)

だから私の質問は、この「リンクハッキング」なしで同じことを達成することは可能ですか?ParentModelまた、子供がおもちゃを持っているかどうかをチェンジリストの別の列に示すことは可能ですか?

4

1 に答える 1

4

list_children列を表示するあなたのアプローチは正しいと思います。「リンクハッキング」について心配する必要はありません。問題ありません。

オブジェクトの子のいずれかにおもちゃがあるかどうかを示す列を表示するには、ParentAdminクラスで別のメソッドを定義しlist_display、前と同じように追加します。

class ParentAdmin(admin.ModelAdmin):
    list_display = ('id', 'some_col', 'some_other', 'list_children', 'children_has_toys')
    ...
    def children_has_toys(self, obj):
        """
        Returns 'yes' if any of the object's children has toys, otherwise 'no'
        """
        return ToyModel.objects.filter(child_owner__parent=obj).exists()
    children_has_toys.boolean = True

設定boolean=Trueは、Djangoがブールフィールドの場合と同じように「オン」または「オフ」アイコンをレンダリングすることを意味します。このアプローチでは、親ごとに1つのクエリ(つまり、O(n))が必要であることに注意してください。本番環境で許容できるパフォーマンスが得られるかどうかを確認するためにテストする必要があります。

于 2011-12-18T11:36:54.390 に答える