2011-07-15 4 views
13

Dans l'administrateur django, en utilisant django 1.2, j'essaie d'ajouter un InlineModelAdmin pour appliquer un commentaire sur save lorsqu'une modification est apportée à une entrée. (Une entrée devrait avoir un "ChangeComment" pour chaque édition).Limiter le sous-jeu d'entrées affichées pour un administrateur django Inline

Je ne veux pas afficher les entrées précédentes, donc je suis en train de forcer le formset.queryset de ChangeCommentInline être vide, en créant NoCommentsInlineFormset et l'affectation du formset dans mon ChangeCommentInline, mais est toujours en renvoyant les entrées existantes.

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

Note - Dans le lien ci-dessus, ils utilisent BaseModelFormset, j'utilise BaseInlineFormset, que je pense peut-être la question. Si j'échange BaseInlineFormset avec BaseModelFormset Je reçois une erreur à propos de "instance" qui n'existe pas.

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,) 

peut limiter les entrées de ChangeComment affichées dans le Inline faire, ou est-il une meilleure façon de gérer cette situation?

+0

Jetez un oeil à BaseModelAdmin: def queryset (auto, demande): "" » Renvoie un QuerySet de toutes les instances de modèles qui peuvent être modifiés par la Ce site est utilisé par changelist_view "" " – benjaoming

+1

... ce que vous devez faire est d'écraser la méthode queryset sur votre InlineModelAdmin. – benjaoming

+0

ok, je vais essayer. Merci!(allez-y et ajoutez-le comme une réponse si vous voulez plus de rep) – monkut

Répondre

14

Comme benjaoming mentionné dans les commentaires, il était nécessaire de remplacer la méthode get_queryset() dans le InlineModelAdmin. Il n'était pas nécessaire de remplacer et de joindre un nouveau formset à la définition InlineModelAdmin comme je le pensais initialement.

Voici la mise en œuvre résulte:

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

Il est à noter qu'à partir de Django 1.6 les méthodes 'queryset()' sont appelées 'get_queryset()'. – gregoltsov

+0

@GregoryGoltsov convenu: fixe. Avant Django 1.6, la méthode s'appelait 'queryset()'. – piro

3

Je vous utilisez en supposant un

models.ForeignKey(EntryAdmin) 

dans votre modèle ChangeComment. mais si vous voulez un seul commentaire pour chaque EntryAdmin, votre place devrait utiliser un:

models.OneToOneField(EntryAdmin) 

Et vous ne serez pas besoin de votre NoCommentsInlineFormset ni votre classe en ligne. C'est ce que je ferais.

ÉDITÉ

Ok alors si vous voulez conserver un historique des commentaires, vous pouvez remplacer le queryset dans le NoCommentsInlineFormset comme:

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

Cela devrait fonctionner.

+0

J'essaie d'avoir un "commentaire" pour * chaque * édition de l'entrée ForeignKey donnée, et de maintenir cet historique des commentaires. Donc, si 5 changements ont été faits, il y aurait 5 entrées ChangeComment dans la base de données, une pour chaque édition. Si je le changeais en OneToOneField, ne permettrait-il pas un seul commentaire par entrée? – monkut

+0

Oui. Je pense que la solution la plus simple serait de remplacer le jeu de requête de votre formulaire et de faire quelque chose comme je l'ai fait dans ma réponse éditée. –

+0

J'ai essayé de surcharger le jeu de requête comme vous l'avez mentionné, mais j'ai eu l'erreur "queryset" non appelable. Il s'avère que la méthode queryset * * dans InlineModelAdmin doit être remplacée. – monkut

Questions connexes