2011-07-15 19 views
13

django 1.2では、エントリを変更したときにInlineModelAdminを追加して保存時にコメントを適用しようとしています。 (エントリはすべての編集に対して「ChangeComment」を持つことが期待されます)。django管理者用に表示されるエントリのクエリーセットを制限するInline

私は以前のエントリを表示したくないので、私はNoCommentsInlineFormsetを作成し、私のChangeCommentInlineでフォームセットを割り当てることによって、空にChangeCommentInlineのformset.querysetを強制しようとしているが、あるい既存のエントリを返します。

https://docs.djangoproject.com/en/1.3/topics/forms/modelforms/#changing-the-queryset

注 - 彼らはBaseModelFormsetを使用する上記のリンクでは、私が問題になることがあり期待BaseInlineFormsetを、使用しています。私が交換した場合BaseInlineFormsetBaseModelFormset「インスタンス」が存在しないというエラーが表示されます。

admin.py

class NoCommentsInlineFormset(models.BaseInlineFormset): 
    def __init__(self, *args, **kwargs): 
     super(NoCommentsInlineFormset, self).__init__(*args, **kwargs) 
     self.queryset = ChangeComment.objects.none() 


class ChangeCommentInline(admin.StackedInline): 
    model = ChangeComment 
    extra = 1 
    exclude = ("user",) 
    formset = NoCommentsInlineFormset 

    def save_model(self, request, obj, form, change): 
     """auto-assign logined in user to comment""" 
     if not change: 
      obj.user = request.user 
     obj.save()  


class EntryAdmin(admin.ModelAdmin): 
    inlines = (ChangeCommentInline,) 

行うことがインラインで表示さChangeCommentエントリを制限し、またはこれを処理するためのより良い方法がありますができますか?

+0

はBaseModelAdminを見てください: デフクエリセット(自己、リクエスト): 「」」で編集することができ、すべてのモデルインスタンスのクエリセットを返します 管理サイト。これはchangelist_viewで使用されています。 "" " – benjaoming

+1

... InlineModelAdminのクエリーセットメソッドを上書きする必要があります。 – benjaoming

+0

よろしくお願いします。ありがとう!(先に進み、より多くの担当者が必要な場合は答えとして追加してください) – monkut

答えて

14

コメントに記載されているように、メソッドを無効にする必要がありました。InlineModelAdmin。私が最初に考えたように、新しいフォームセットをオーバーライドしてInlineModelAdmin定義に添付する必要はありませんでした。ここで

は、得られた実装です:

class ChangeCommentInline(admin.StackedInline): 
    """For allowing logged in user to add change comment""" 
    model = ChangeComment 
    extra = 1 
    exclude = ("user",) # auto-update user field in save_formset method of parent modeladmin. 


    def get_queryset(self, request): 
     """Alter the queryset to return no existing entries""" 
     # get the existing query set, then empty it. 
     qs = super(ChangeCommentInline, self).get_queryset(request) 
     return qs.none() 
+12

Django 1.6以降、 'queryset()'メソッドは 'get_queryset()'と呼ばれています。 – gregoltsov

+0

@GregoryGoltsovの同意:修正済み。 Django 1.6より前のこのメソッドは 'queryset()'と呼ばれていました。 – piro

3

私はあなたのChangeCommentモデルに

models.ForeignKey(EntryAdmin) 

を使用していると仮定しています。あなたは、各EntryAdmin 1件のだけのコメントをしたい場合は、あなたの代わりに使用する必要があります。

models.OneToOneField(EntryAdmin) 

そして、あなたはあなたのNoCommentsInlineFormsetもあなたのインラインクラスを必要としません。 それは私がやることです。これは動作するはず

def __init__(self, *args, **kwargs): 
    super(NoCommentsInlineFormset, self).__init__(*args, **kwargs) 
    self.queryset = ChangeComment.objects.order_by('-created_at')[:1] 

:あなたは、コメントの履歴を保持したい場合は

EDITED

[OK]を、その後、あなたはようNoCommentsInlineFormset でクエリセットをオーバーライドすることができます。

+0

私は与えられたForeignKey Entryの*各*編集のための "コメント"を持ち、そのコメント履歴を維持しようとしています。したがって、5つの変更が行われた場合、dbに5つのChangeCommentエントリがあります。各エントリは編集ごとに1つです。 OneToOneFieldに変更しても、エントリごとに1つのコメントしか許可されませんか? – monkut

+0

はい。私は、単純な解決策は、あなたのフォームのクエリセットをオーバーライドして、私が編集した答えのようにすることだと思います。 –

+0

あなたが言及したようにクエリーセットをオーバーライドしようとしましたが、 "queryset"というエラーがあります。オーバーライドする必要があるInlineModelAdminのqueryset *メソッド*を有効にします。 – monkut

関連する問題