2

だから私はこのようなモデルを持っています:

class Celebrity(models.Model):
    #30+ fields here ...

class HoneyBadger(models.Model):
    name = models.CharField(max_length=10)
    celebrity_owner = models.ForeignKey(Celebrity)

次に、HoneyBadger の管理インターフェイスに、クリーチャーの名前と有名人の所有者フィールドを表示するようにします。

標準的なアドバイスは、次のようなことです。

class HoneyBadger(models.Model):
    name = models.CharField(max_length=10)
    celebrity_owner = models.ForeignKey(Celebrity)

    def owner_birth_date(self):
        return self.celebrity_owner.birth_date
    #And so on for every other field in celebrity_owner

そして、管理者でそれらのメソッドを参照します。

代わりに、すべての入力を節約する方法が必要です!

怠惰なショートカットでの私の最初の試みは次のとおりです。

class HoneyBadger(models.Model):
    name = models.CharField(max_length=10)
    celebrity_owner = models.ForeignKey(Celebrity)

    def __getattr__(self, name):
        """Dynamically make derived fields for celebrity_owner fields so I don't have to type out"""
        field_lookup_prefix = 'celebrity_owner_field_'
        if name.startswith(field_lookup_prefix):
            field_name = name[len(field_lookup_prefix):]
            def wrapper(*args, **kwargs):
                return getattr(self.celebrity_owner, field_name)
            return wrapper
        else:
            raise AttributeError('%s not found' % name)

シェルで実行するとうまくいきますが、Django 管理者は気に入っていません。次のエラーが表示されます。

ImproperlyConfigured at /admin/tracker/

HoneyBadgerAdmin.list_display[5], 'celebrity_owner_field_birth_date' is not a callable or an attribute of 'HoneyBadgerAdmin' or found in the model 'HoneyBadger'.

自分のコードを管理者と連携させる方法を知っている人はいますか? または、有名人のフィールドごとにメソッドを入力するのを節約する別の方法があるかどうかは? (おそらく、ある種のランタイム モンキー パッチ?)

4

2 に答える 2

2

目的を達成するための回避策が 2 つあります。

  1. HoneyBadger Admin で Celebrity オブジェクトへのリンクを提供します。

    def celebrity_link(self):
        return '<a href="%s">%s</a>' % (reverse('admin:appname_celebrity_change',args=(self.celebrity_owner.id,)), self.celebrity_owner.celeb_name)
    
    celebrity_link.allow_tags = True
    celebrity_link.short_description = u'Celebrity'
    
    class HoneyBadgerAdmin(admin.ModelAdmin):
        list_display = [..., celebrity_link, ...]
    
  2. 次の解決策は少し複雑ですが、私たちが望んでいることを正確に実行します: カスタム管理テンプレートを定義します。基本的に、変更フォームを django ソースからコピーし、有名人の情報を表示するカスタム コードを追加します。このドキュメントを参照してください。

于 2013-06-13T09:18:03.633 に答える
1

name フィールドを使用して Celebrity クラスを拡張したいようですね。そのクラスを HoneyBadger クラスに継承してみませんか?

class HoneyBadger(Celebrity):
    name = models.CharField(max_length=10)

(これを機能させるには、最初に古い HoneyBadger テーブルをデータベースから削除する必要がある場合があります。)

于 2013-06-12T15:06:02.467 に答える