2011-12-18 4 views
7

Je les modèles mis en place comme ceci:Django admin changelist filtrage/liens vers d'autres modèles

class ParentModel(models.Model): 
    some_col = models.IntegerField() 
    some_other = models.CharField() 

class ChildModel(models.Model) 
    parent = models.ForeignKey(ParentModel, related_name='children') 

class ToyModel(models.Model) 
    child_owner = models.ForeignKey(ChildModel, related_name='toys') 

Maintenant, dans mon panneau d'administration quand j'ouvre la liste des modifications pour ParentModel Je veux un nouveau champ/colonne dans la list_display avec un lien pour ouvrir la liste des modifications du ChildModel mais avec un filtre appliqué pour afficher uniquement les enfants du parent sélectionné. Pour l'instant je l'ai réalisé avec cette méthode, mais je pense qu'il ya un propre façon de le faire, je ne sais pas comment:

class ParentAdmin(admin.ModelAdmin) 
    list_display = ('id', 'some_col', 'some_other', 'list_children') 
    def list_children(self, obj): 
     url = urlresolvers.reverse('admin:appname_childmodel_changelist') 
     return '<a href="{0}?parent__id__exact={1}">List children</a>'.format(url, obj.id) 
    list_children.allow_tags = True 
    list_children.short_description = 'Children'   

admin.site.register(Parent, ParentAdmin) 

Ma question est, est-il possible d'obtenir le même sans que cela "lien piratage"? Est-il également possible d'indiquer dans une colonne séparée dans la liste de modifications ParentModel, si l'un de ses enfants a des jouets?

Répondre

2

Je pense que votre approche pour afficher la colonne list_children est correcte. Ne vous inquiétez pas du 'piratage de lien', ça va.

Pour afficher une colonne indiquant si l'un des enfants de l'objet possède des jouets, définissez simplement une autre méthode sur la classe ParentAdmin et ajoutez-la à comme précédemment.

class ParentAdmin(admin.ModelAdmin): 
    list_display = ('id', 'some_col', 'some_other', 'list_children', 'children_has_toys') 
    ... 
    def children_has_toys(self, obj): 
     """ 
     Returns 'yes' if any of the object's children has toys, otherwise 'no' 
     """ 
     return ToyModel.objects.filter(child_owner__parent=obj).exists() 
    children_has_toys.boolean = True 

Réglage boolean=True signifie Django rend le « on » ou « off » icônes comme il le fait pour les champs booléens. Notez que cette approche nécessite une requête par parent (c'est-à-dire O (n)). Vous devrez tester pour voir si vous obtenez des performances acceptables en production.

+0

Merci pour votre réponse, cela m'a vraiment beaucoup aidé. Je suis surpris que django n'ait pas un moyen plus élégant pour la fonction de lien liste de modifications. En tout cas merci, votre aide a résolu tous mes problèmes. –