2013-02-14 11 views
5

Sto creando un semplice CMS basato su piramide che utilizza l'attraversamento. Esiste una classe denominata Collection, che ha alcune sottoclassi come NewsCollection, GalleriesCollection ecc.È possibile utilizzare una vista configurata per la superclasse se in Pyramid è stata configurata una vista per una classe?

Ho bisogno di due tipi di viste per visualizzare queste raccolte. La vista frontend, html e il backend, json view (il pannello di amministrazione usa dgrid per visualizzare i dati). La vista back-end può essere generica, in ogni caso scarica i dati JSON. La vista frontend non dovrebbe - ci sarà un modello personalizzato per ogni tipo di dati.

Il problema è: quando configuro vista in questo modo:

@view_config(context=Collection, xhr=True, renderer='json', accept='application/json') 

funziona correttamente. Tuttavia, non appena aggiungo una qualsiasi vista configurata per NewsCollection, questa ha la precedenza. Anche se inserisco i predicati specificamente in conflitto con la configurazione precedente (ad esempio), la vista sopra riportata non verrà ancora chiamata. Invece otterrò un 'errore di predicato'.

La mia domanda è - Posso fare qualcosa per rendere la vista configurata per Collection essere chiamato quando ci sono anche viste per NewsCollection? O devo usare un altro design (come url dispatch o aggiungere la stessa vista più volte per diversi tipi di risorse)

risposta

6

Ho provato a costruire un sistema molto simile e ho scoperto lo stesso problema - in effetti, ecco il ticket in Pyramid bug tracker: https://github.com/Pylons/pyramid/issues/409

In breve, non tutti i predicati di vista in Pyramid sono uguali - context è un caso speciale. Una vista viene prima abbinata usando context e quindi la selezione viene ristretta usando altri predicati.

C'è anche un recente pull request che farebbe in modo che Pyramid si comporti come ci si aspetterebbe (e io), tuttavia, dalla discussione in cui vedo che non è molto probabile che venga adottato a causa di possibili compromessi in termini di prestazioni.

(UPDATE: la richiesta di pull è stata fusa marzo 2013, quindi credo che dovrebbe essere disponibile il rilascio seguente 1.4)

Un work-around è quello di utilizzare un predicato personalizzato:

def context_implements(*types): 
    """ 
    A custom predicate to implement matching views to resources which 
    implement more than one interface - in this situation Pyramid has 
    trouble matching views to the second registered interface. See 
    https://github.com/Pylons/pyramid/issues/409#issuecomment-3578518 

    Accepts a list of interfaces - if ANY of them are implemented the function 
    returns True 
    """ 
    def inner(context, request): 
     for typ in types: 
      if typ.providedBy(context): 
       return True 
     return False 
    return inner 


@view_config(context=ICollection, 
    custom_predicates=(context_implements(INewsCollection),) 
    ) 
def news_collection_view(context, request): 
    .... 
Problemi correlati