0

管理者の一般的なインライン フォームに奇妙な問題があります。異なる数のビデオをプロジェクトにリンクし、多くのプロジェクトをビデオにリンクできるようにする必要があるため、VideoLinkを介したManyToMany 関係を持つメイン プロジェクトとビデオの 2 つのモデルがあります。

class VideoLink(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    video = models.ForeignKey(Video)

class Project(models.Model):
    name = models.CharField(max_length=50)
    image_set = generic.GenericRelation('Image')

ここでは Video モデルを示しませんでしたが、私の質問にとっては重要ではありません。

必要なのは、メイン オブジェクト (プロジェクト) にリンクされた新しい関連オブジェクト (VideoLink) を 2 つの方法で定義することだけです。

  • 管理インラインフォーム内のビデオを選択します (これは非常にうまく機能します!)
  • 偽の video_url フィールドで新しいビデオの URL を定義し、新しい Video オブジェクトを作成し、メイン (プロジェクト) オブジェクトと新しい (ビデオ) オブジェクトの間に新しい VideoLink オブジェクトを作成します。

2 番目のケースでは、中間機能を設定する必要があります。新しいビデオの URL ( http://www.youtube.com/watch?v=WIXVzeB0DUoなど) を処理し、新しい Video オブジェクトを作成して youtube.com と同期します。私は最善の方法だと思います - これを AdminVideoLink のフォームのclean メソッドに入れます。よろしいですか?

だから、私はこのコードを書きました:

class VideoForm(forms.ModelForm):

    # new field for absolute video urls
    video_url = forms.CharField()

    def clean(self):
        cleaned_data = self.cleaned_data
        if not cleaned_data.get('id') and not cleaned_data.get('video') and cleaned_data.get('video_url'):
            ... some extra functionality:
            1) get id from video_url
            2) create new Video object with id
            3) define cleaned_data['video'] = <Video object>
             ....  

        return cleaned_data

class VideoInline(generic.GenericTabularInline):
    model = VideoLink
    form = VideoForm

class ProjectAdmin(admin.ModelAdmin):
    inlines = [VideoInline]

しかし、フォームを保存した後は毎回、管理インライン フォーム内にエラーが表示されます: ビデオ オブジェクトの近くで選択 - 「フィールドが必要です」(私の翻訳)。しかし、このフィールドを clean メソッド内に設定しました。私はそれをチェックします: self.cleaned_data['video'] には、作成して同期したばかりの新しい Video オブジェクトが含まれています。

もう 1 つの非常に奇妙な問題: このclean メソッド内で親インスタンス (メインの Project オブジェクト) が見つかりません。単純な ManyToMany オブジェクト (ジェネリック リレーションと generic.GenericTabularInline フォームなし) で同じことを行うと、インライン フォーム内にビデオ フィールドとプロジェクト フィールドの両方が表示されますが、一般的なケースでは表示されません。

関連する投稿を確認しましたが、答えが見つかりませんでした。

4

1 に答える 1

0

この問題は非常に簡単に解決できます。required =Falseをインライン フォームに追加するだけです。

class VideoForm(forms.ModelForm):

    video_url = forms.CharField(required=False, widget=AdminVideoPreviewWidget())

    def __init__(self, *args, **kwargs):
        super(VideoForm, self).__init__(*args, **kwargs)
        self.fields['video'].required = False

    ....

これにより、新しい Video オブジェクトを作成して同期した後、ビデオ フィールドを手動で埋めることができます。

于 2009-06-03T14:56:32.923 に答える