2012-05-06 7 views
6

Sto lavorando con alcune semplici risorse django-tastypie con il seguente problema:Come posso fare in modo che Django-Tastypie sovrascriva una risorsa se già esiste?

Immagina di costruire un semplice sistema di valutazione. Ho una risorsa, chiamiamola Rating che ha sia un User e un Comment. Ogni utente ha al massimo una valutazione per commento.

Mi piacerebbe creare una risorsa generica che richiede una tupla ('user', 'comment'). Quindi, ogni volta che eseguo un POST con un nuovo Rating, desidero controllare i campi user e comment per verificare se esiste già una valutazione corrispondente a entrambi i campi. Se lo fa, sovrascrivi la risorsa esistente, altrimenti crea una nuova risorsa (in modo che ogni chiamata API passerà sempre su Django unique_together).

Sto lavorando con obj_get come punto di partenza, ma ho difficoltà a capire come sovrascriverlo correttamente per ottenere questo comportamento.

risposta

6

A seguito della discussione su IRC in #tastypie:

Si consiglia di non alterare il comportamento standard API, in quanto questo può essere pericoloso, nel senso che i clienti non vedranno un comportamento coerente in tutta l'API.

Una soluzione è lasciare che Tastypie restituisca una risposta 4xx quando tenta di creare il Rating, e in questo caso il client avrebbe PATCH la valutazione esistente.

Se, tuttavia, il miglioramento delle prestazioni è veramente necessario, è necessario modificare il comportamento solo se il client richiede formalmente questo. Che nel tuo caso significherebbe aggiungere un parametro replace_existing_rating=True alla richiesta POST.

Quindi nel tuo caso, se si ha decide che ha bisogno il miglioramento delle prestazioni, si potrebbe:

class CommentResource(ModelResource): 
    def obj_create(self, bundle, request=None, **kwargs): 
     if bundle.data.get("replace_existing_rating", False): 
      try: 
       bundle.obj = self._meta.object_class._default_manager.get(**conditions) 
      except self._meta.object_class.DoesNotExist: 
       bundle.obj = self._meta.object_class()