2010-12-12 38 views
0

J'ai eu des difficultés avec ce problème pendant quelques heures - je sais qu'il y a probablement une solution simple que je néglige.Relation entre le modèle et le modèle html

J'ai une relation un à plusieurs avec mes modèles.

J'ai besoin de retourner toutes les lignes d'un objet avec les lignes de l'objet associé.

Dans un sens, j'ai ceci:

object 
object 
    object_relationship.property 
    object_relationship.property 
object 
    object_relationship.property 
object 

Maintenant - je peux courir à travers toutes ces belles, mais je tombe sur un problème quand je veux envoyer tous ces éléments sur le modèle html.

Je peux renvoyer l'objet - mais comment renvoyer l'object_relationship dans l'ordre indiqué ci-dessus?

Est-ce que cela a du sens?

Répondre

0

Ma première suggestion est de dénormaliser les données si vous allez faire beaucoup de rapports comme ça. Par exemple, vous pourriez peut-être inclure object.name sur l'entité object_relationship.

Cela dit, vous pouvez envoyer une liste de dicts à votre modèle, alors peut-être quelque chose comme:

data = [] 
for entity in your_query: 
    children = [{'name': child.name} for child in entity.object_relation] 
    data.append({'name': object.name, 
       'children': children, 
       ... 
       }) 

passe ensuite la liste data à votre modèle, et le traiter.

S'il vous plaît noter, cela fonctionnera très mal. Il va exécuter une autre requête pour tous les l'un des éléments de votre première requête. Utilisez Appstats pour profiler votre application.

+0

Merci Robert - cela a fait l'affaire - je suis d'accord sur la performance, nous aurons peut-être besoin de dénormaliser celui-ci bientôt. – sampyxis

2

Vous ne pourriez pas besoin de trop vous inquiéter à ce sujet, acutally ... regardez ces modèles:

class Venue(base.NamedEntity, HasPerformances, HasUrl, HasLocation): 
    city = db.ReferenceProperty(City, collection_name='venues') 
    url = db.StringProperty(required=True, validator=validators.validate_url) 
    location = db.GeoPtProperty() 

class Performance(base.Entity): 
    show = db.ReferenceProperty(Show, collection_name='performances', required=True) 
    utc_date_time = db.DateTimeProperty(required=True) 
    venue = db.ReferenceProperty(Venue, collection_name='performances', required=True) 

Dans un cas comme celui-ci, rien ne vous empêche d'utiliser venue.performances à partir soit du code ou des modèles et le traitement comme une liste. L'API déclenche automatiquement les requêtes au besoin pour récupérer les objets réels. La même chose vaut pour performance.venue.

Le seul problème ici est la performance - vous avez une variante du n+1 problem à gérer. Il existe des solutions de contournement, cependant, comme this article par Nick Johnson. Je suggère de lire le code de l'API aussi ... il est intéressant de lire comment la propriété est capturée et déréférencée.