2017-07-06 2 views
2

Je suis en train de configurer un site web Wagtail.Détection des types de pages parent et enfant avec Python en utilisant Wagtail CMS

Il y aura une page d'événement avec des événements en tant que pages enfants.

Chaque page d'événement peut également avoir des pages enfants, si elle fait partie d'une série d'événements.

L'événement principal affichera les événements enfants sous la forme d'une série de liens sur la page. Les événements enfants doivent également afficher l'événement parent et ses propres frères et sœurs.

Dans models.py j'ai une classe d'événement. Jusqu'à présent, je suis la détection des enfants, frères et sœurs, parents comme ceci:

@property 
def childpages(self): 
    event_children = Event.objects.live().descendant_of(self) 
    return event_children 

@property 
def parentpage(self): 
    event_parent = self.get_parent() 
    return event_parent 

@property 
def siblingpages(self): 
    event_siblings = Event.objects.live().sibling_of(self, inclusive=False) 
    return event_siblings 

est-il un moyen de savoir ce que le type de page parent est? Si c'est l'index des événements, je ne voudrais pas l'afficher sur la page de l'événement. Je ne voudrais pas non plus que les pages de l'événement principal montrent des frères et soeurs.

J'ai essayé plusieurs choses avec not_child_of (somepage) mais je ne sais pas trop comment l'utiliser. Qu'est-ce que 'somepage' référence? Une classe, une variable? Je suis habitué à Javascript et plutôt nouveau à Python.

Répondre

1

Voilà comment je l'écrire:

@property 
def parent_event(self): 
    parent_page = self.get_parent() 
    if parent_page.specific_class == Event: 
     return parent_page.specific # or just `return parent_page` if you don't need the extra detail from that page 
    else: 
     return None 

@property 
def sibling_events(self): 
    parent_page = self.get_parent() 
    if parent_page.specific_class == Event: 
     return Event.objects.live().sibling_of(self, inclusive=False) 
    else: 
     # this is not a child event, so don't return siblings 
     return Event.objects.none() 

En Python, la manière standard de vérifier si un objet est une instance d'une classe donnée (par exemple en termes Bergeronnette, si une page est d'un particulier type) est isinstance(parent_page, Event).

Cependant, avec Bergeronnette il y a une complication supplémentaire - quand vous traversez de haut en bas l'arborescence des pages en utilisant des méthodes comme get_parent et get_children, il n'y a aucun moyen pour elle de savoir à l'avance quel type de page, il va revenir - donc, pour Pour des raisons de performances, il renverra un objet "minimal" de type Page qui inclut uniquement les propriétés communes à toutes les pages, telles que title. Donc, self.get_parent().title fonctionnerait, mais self.get_parent().start_date ne fonctionnerait pas. Pour transformer cela en un "vrai" objet du type approprié, vous devez accéder à la propriété specific, qui fera une demande de base de données supplémentaire en coulisse pour remplir le détail manquant. (Notez que ceci ne s'applique pas lorsque vous exécutez une requête qui demande explicitement un type spécifique de page: avec une requête comme Event.objects.sibling_of(self), nous savons que nous obtiendrons Event pages en arrière, donc nous n'avons pas besoin . appeler specific sur les résultats)

Ainsi, if isinstance(parent_page, Event): ne fonctionnerait pas - il sera toujours faux, parce qu'à ce moment parent_page est un objet Page de base (indépendamment du fait que la page est vraiment un Event ou un EventIndex).

if isinstance(parent_page.specific, Event):serait travail, mais il est un peu inefficace, car dans le cas où parent_page est la page d'index de l'événement, vous tirer hors d'une demande de base de données supplémentaire que vous n'avez pas vraiment besoin. Une meilleure alternative consiste à utiliser parent_page.specific_class, qui vous indique le type spécifique de la page sans déclencher cette requête de base de données supplémentaire.