11

画像、動画、その他のメディア タイプを含むことができる Post オブジェクトがあるとします。a を使用しGenericForeignKeyてそれらをリンクできます。何かのようなもの:

class Post(models.Model):
  title = models.CharField(...)
  text = models.TextField(...)

class AudioMedia(models.Model):
  ...

class VideoMedia(models.Model):
  ...

class ImageMedia(models.Model):
  ...

class MediaObject(models.Model):
  post = models.ForeignKey(Post)
  order = models.IntegerField()

  content_type_media = models.ForeignKey(
    ContentType, limit_choices_to={
      'model__in': (
        'audiomedia',
        'imagemedia',
        'videomedia')
  })

  object_id_media = models.PositiveIntegerField()
  obj = generic.GenericForeignKey('content_type_media', 'object_id_media')

これで、次のような管理インターフェイスを簡単に作成できます。

class MediaObjectAdminInLine(admin.StackedInline):
  model = MediaObject
  ct_field = "content_type_media"
  ct_fk_field = "object_id_media"
  extra = 0

class PostAdmin(admin.ModelAdmin):
  inlines = [MediaObjectAdminInLine]

ここで質問です:) admin/ では、新しい投稿を簡単に作成できます。投稿には、MediaObject を簡単に追加できます。パネルには、タイプ (オーディオ、ビデオなど) を選択するためのドロップダウン メニューがありますが、Post にリンクするオブジェクトの IDを手動で入力する必要があります。

grappelli を含むさまざまな拡張機能を試しました。ここにリンクするオブジェクトの IDを検索する機能を提供するものもあります。ここにオブジェクトを追加する機能が必要です。たとえば、ドロップダウンから選択したものに応じて、AudioMedia、VideoMedia、ImageMedia を追加します。

助言がありますか?

4

3 に答える 3

7

これを実現するには、かなりの作業が必要です。

  • ドロップダウンから選択したモデル タイプに基づいて、モデル フォームを動的に表示するよう管理者に依頼しています。
  • Django の管理者はそれを行いません (既知の拡張も行いません)。

これを機能させるには、次のことを行う必要があります。

  1. モデル選択ドロップダウンの onchange をキャプチャするカスタム JavaScript イベント ハンドラーを記述します。
  2. 次に、Django の管理者を呼び出し、そのモデルのインライン モデルフォームを要求します。
  3. そのモデル フォームで現在の HTML ページを更新します。
  4. 次に、親モデルのモデルフォームの save() メソッドをインターセプトして、処理している子モデルフォームを特定し、データベースに正しく保存する必要があります。
  5. 次に、親モデルのモデルフォームを取得して、子のモデルに依存する適切な子モデルのモデルフォームを正しく表示する方法を整理する必要があります。

気が遠くなるような?です。

より簡単な方法は次のとおりです。

単一の「メディア」モデルを持つだけです。モデルには、タイプの 1 つに対してのみ有効なフィールドがいくつかあります (クロスオーバーはたくさんありますが)。

単一のメディア タイプに固有のフィールドには、そのメディア タイプのプレフィックスを付けて名前を付けます (image_size', or例: video_title`)。

メディア タイプのドロップダウンに基づいてフィールドを選択的に表示および非表示にする JavaScript ハンドラーを ModelAdmin にアタッチします。このようなもの:

class MediaAdmin(admin.ModelAdmin):
    class Meta:
        js = ["js/media-types.js",]

    // media-type.js
(function($) {
    $(document).ready(function(){
        $('.module[id^=module] .row').hide();
        $('.module[id^=module] .row.module').show();
        $('.module[id^=module] .row.module select').each(function(){
            if ($(this).val() != '') 
            {
                var group = $(this).parent().parent().parent().parent();
                var field = $(this).parent().parent().parent();
                var mtype = $(this).val().toLowerCase();
                if (mtype != '') 
                {               
                    $('.row', group).not(field).slideUp('fast');
                    $('.row[class*="'+mtype+'"]', group).slideDown('fast');
                    $('.row[class*="all"]', group).slideDown('fast');
                }
                else
                {
                    $('.row', group).not(field).slideUp('fast');
                }
            }
        });
        $('.module[id^=module] .row.module select').change(function(){
            var group = $(this).parent().parent().parent().parent();
            var field = $(this).parent().parent().parent();
            var mtype = $(this).val().toLowerCase();
            if (mtype != '') 
            {
                $('.row', group).not(field).slideUp('fast');
                $('.row[class*="'+mtype+'"]', group).slideDown('fast');
                $('.row[class*="all"]', group).slideDown('fast');
            }
            else
            {
                $('.row', group).not(field).slideUp('fast');
            }
        });
    });
})(django.jQuery);
于 2013-02-25T10:18:50.067 に答える
1

これはかなり古いことだと思いますが、これを検索したときの最初の結果です。

django-admin-genericfkはまさに必要なことを行います。

于 2015-09-24T10:04:47.407 に答える