2014-06-11 12 views
9

Uso Django Rest Framework e devo aggiungere dati aggiuntivi a un set di risultati. In particolare, in cui di solito si hanno:Aggiunta di dati aggiuntivi ai risultati di Django Rest Framework per l'intero set di risultati

{ 
    "count": 45, 
    "next": "http://localhost:8000/foo/bar?page=2", 
    "previous": null, 
    "results": [ 
     {...} 
    ] 
} 

vorrei aggiungere conteggi in più in questo modo:

{ 
    "count": 45, 
    "10_mi_count": 10, 
    "20_mi_count": 30, 
    "30_mi_count": 45, 
    "next": "http://localhost:8000/foo/bar?page=2", 
    "previous": null, 
    "results": [ 
     {...} 
    ] 
} 

I conteggi supplementari in questo esempio sono proprio come molti degli oggetti hanno una distanza campo con un valore inferiore alle miglia descritte nel tasto.

Il mio problema è che non ho idea di dove sia il posto migliore per estendere e inserire questo comportamento.

Idealmente mi piacerebbe che funzionasse anche se i risultati sono impaginati, senza fare ipotesi.

Quello che sto cercando è un cenno nella direzione giusta (e perché è il posto giusto per farlo).

Ho controllato i documenti e non riesco a trovare nulla che descriva come aggiungere cose come questa, ma sarei più che felice di essere smentito su quel punteggio.

risposta

18

Dal momento che ti sembra di essere utilizzando uno dei ListViews dal Framework resto, si potrebbe sovrascrivere il metodo list() nella classe e impostare i nuovi valori sui dati risultanti, in questo modo:

def list(self, request, *args, **kwargs): 
     response = super(YourClass, self).list(request, args, kwargs) 
     # Add data to response.data Example for your object: 
     response.data['10_mi_count'] = 10 # Or wherever you get this values from 
     response.data['20_mi_count'] = 30 
     response.data['30_mi_count'] = 45 
     return response 

Avviso che la classe deve ereditare ListModelMixin direttamente o tramite un GenericView dall'API Rest Framework (http://www.django-rest-framework.org/api-guide/generic-views#listmodelmixin). Non so davvero se è il modo giusto per farlo, ma è una soluzione rapida.

Spero che aiuti!

+0

Hey, sono andato con un metodo diverso, alla fine, che ho descritto nella mia risposta. Questa è una buona alternativa, quindi grazie mille. –

+0

Ho fatto una variazione di questo che ha funzionato alla grande. Volevo alcuni dati min-max aggregati restituiti con la mia query per alcuni intervalli di cursori. Ho copiato completamente l'implementazione del metodo list dalla classe genitore nella mia sottoclasse. Ottiene l'oggetto queryset in modo da poterlo modificare per eseguire aggregati sul set di query e aggiungere i risultati alla risposta. Grazie! – t1m0

3

Alla fine ho appena creato una paginazione serializzatore con un campo in questo modo:

class DistanceCountField(serializers.Field): 
    def to_native(self, value): 
     try: 
      distance_counts = { 
       '1_mile': self._count_lte_miles(value, 1), 
       '5_mile': self._count_lte_miles(value, 5), 
       '10_mile': self._count_lte_miles(value, 10), 
       '20_mile': self._count_lte_miles(value, 20), 
      } 
     except FieldError: 
      distance_counts = None 

     return distance_counts 

    def _count_lte_miles(self, value, miles): 
     meters = miles * 1609.344 
     return value.filter(distance__lte=meters).count() 


class PaginatedCountSerializer(pagination.PaginationSerializer): 
    distance_counts = DistanceCountField(source='paginator.object_list') 

    class Meta: 
     # Class omitted, just a standard model serializer 
     object_serializer_class = MyModelSerializer 

Ho anche aggiunto un'annotazione distanza di ciascun oggetto nel queryset per il filtraggio a lavorare.

1

Utilizzare SerializerMethodField come indicato in questo solution.

Può essere utilizzato per aggiungere qualsiasi tipo di dati alla rappresentazione serializzata del proprio oggetto. (REST framework doc)

Esempio dalla documentazione:

from django.contrib.auth.models import User 
from django.utils.timezone import now 
from rest_framework import serializers 

class UserSerializer(serializers.ModelSerializer): 
    days_since_joined = serializers.SerializerMethodField() 

class Meta: 
    model = User 

def get_days_since_joined(self, obj): 
    return (now() - obj.date_joined).days 
+0

Un collegamento a una soluzione è il benvenuto, ma per favore assicuratevi che la vostra risposta sia utile senza: [aggiungere contesto intorno al collegamento] (http: //meta.stackexchange.it/a/8259) così i tuoi utenti avranno un'idea di cosa sia e perché è lì, quindi cita la parte più pertinente della pagina a cui stai collegando nel caso in cui la pagina di destinazione non sia disponibile. [Le risposte che sono poco più di un collegamento potrebbero essere cancellate] (http://stackoverflow.com/help/deleted-answers). – mrun

Problemi correlati