Raw query en Django

Puedes ver la documentación oficial en: (https://docs.djangoproject.com/en/1.8/topics/db/sql/)

El resumen es que permite hacer consultas SQL directamente. Debes tener en cuenta que no todos los motores funcionan igual (Sqlite, Mysql, PostgreSQL...) por lo que tendrás que adecuar la consulta acorde al motor que utilices en tu proyecto.

Es obligatorio que el .raw() devuelva el PrimaryKey del modelo que estás consultando.

Ej.-

Tomando este modelo como ejemplo:

class ActionsArchive(models.Model):
    archive_id = models.IntegerField(primary_key=True, editable=False, blank=True)
    consumer_id = models.ForeignKey(Consumer, related_name='consumer_inbox')
    action_id = models.ForeignKey(Action, related_name='action_inbox')
    created_at = models.IntegerField(default=0,editable=False)

SIEMPRE pedirá que devuelvas el archive id. Esto puede ser un problema, por ejemplo si únicamente quieres obtener las tuplas con un group by consumer id, pues te obliga a agregar al group by el archive_id (Y por tanto, cambia totalmente la consulta). La solución que encontré para este caso concreto, fue cambiar el modelo por el de consumer, haciendo un alias del PK de consumer. Manteniendo la misma SQL en raw, es decir:

Cambiar esto:

query = ActionsArchive.objects.raw('SELECT archive_id, consumer_id_id, action_id_id FROM users_actionsarchive WHERE action_id_id = 2 group by action_id_id,consumer_id_id,archive_id') #users with changed avatar

Por esto:

query = Consumer.objects.raw('SELECT consumer_id_id as consumer_id FROM users_actionsarchive WHERE action_id_id = 2 group by action_id_id,consumer_id_id') #users with changed avatar

El primer caso, devolvía una tupla por cada archive_id. El segundo, agrupa por usuarios y devuelve el mismo número de tuplas que usuarios hay por acción, independientemente de que exista un usuario dos veces dentro de la misma acción.