2015-08-31 16 views
11

Ho una classe Django come segue:Perché Django Queryset dice: TypeError: le aggregazioni complesse richiedono un alias?

class MyModel(models.Model): 
    my_int = models.IntegerField(null=True, blank=True,) 
    created_ts = models.DateTimeField(default=datetime.utcnow, editable=False) 

Quando eseguo il seguente set di query, ottengo un errore:

>>> from django.db.models import Max, F, Func 
>>> MyModel.objects.all().aggregate(Max(Func(F('created_ts'), function='UNIX_TIMESTAMP'))) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "MyVirtualEnv/lib/python2.7/site-packages/django/db/models/query.py", line 297, in aggregate 
    raise TypeError("Complex aggregates require an alias") 
TypeError: Complex aggregates require an alias 

Come si regola il mio set di query in modo che non ottengo questo errore? Voglio trovare l'istanza di MyModel con le ultime create_ts. E voglio usare la funzione UNIX_TIMESTAMP per ottenerlo.

risposta

4

Io non sto correndo la stessa versione Django, ma penso che questo sarà il lavoro:

MyModel.objects.all().aggregate(latest=Max(Func(F('created_ts'), function='UNIX_TIMESTAMP'))) 

Annotare il latest parola chiave argomento in là. Questa è la chiave (credo, ancora non posso testarlo).

2

From the django docs:

aggregate() is a terminal clause for a QuerySet that, when invoked, returns a dictionary of name-value pairs

Esso fornirà automaticamente questo valore in molti casi generici, ad esempio

Sum('items') -> sum_items 

Per la tua ricerca, non è possibile creare un alias di default, quindi è necessario fornire uno. Questo è così la query può restituire un risultato denominato per i valori prodotti. Tutto quello che devi fare è dare al tuo aggregato un alias con nome significativo e tutto dovrebbe funzionare bene:

MyModel.objects.all().aggregate(max_created=Max(Func(F('created_ts'), function='UNIX_TIMESTAMP')))