title: How do you join two tables using Django without using raw sql?
body: <p>Is is possible to programatically join two tables using Django's ORM? I have two models: Topics and Votes. On my template I have a list of topics that users can up/down vote like Reddit. Everything works as it should except for sorting the results. I cannot figure out how to sort an objects list based off the score which is a sum of each object's vote count. I can retrieve the desired data from postgres without any issue:</p>
  
  <pre><code>select i.id, i.title, i.date_created, s.object_id, s.vote, Sum(vote) 
  from topic_topic i, votes s 
  where i.id = s.object_id 
  group by 1, 2, 3, 4, 5 
  order by sum DESC;
  </code></pre>
  
  <p>It returns the desired results:</p>
  
  <pre><code>id | title  |         date_created          | object_id | vote | sum 
  
  11 | sdfg   | 2012-06-04 23:30:17.805671-07 |        11 |    1 |   2
  
   1 | test   | 2012-05-13 17:03:24.206092-07 |         1 |    1 |   2
  
   3 | asdf   | 2012-05-13 19:23:15.059135-07 |         3 |    1 |   2
  
   2 | adsf   | 2012-05-13 19:21:34.180905-07 |         2 |    1 |   2
  
  12 | 11     | 2012-06-04 23:30:54.759158-07 |        12 |    1 |   2
  
   9 | asfd   | 2012-05-24 00:26:26.705843-07 |         9 |   -1 |  -1
  
   4 | asdf   | 2012-05-14 19:59:52.450693-07 |         4 |   -1 |  -2
  </code></pre>
  
  <p>The problem is, I am not sure how to retrieve this as a queryset. At the moment I am using the following to display objects:</p>
  
  <pre><code>topic_list = Topic.objects.all()
  </code></pre>
  
  <p>Everything displays as I would like it to, except for the sort order. I would like the highest score to display first.</p>
  
  <p><strong>Resources I have already looked at:</strong>
  <a href="https://docs.djangoproject.com/en/dev/topics/db/managers/#adding-extra-manager-methods" rel="nofollow noreferrer">https://docs.djangoproject.com/en/dev/topics/db/managers/#adding-extra-manager-methods</a><br>
  <a href="https://stackoverflow.com/questions/629551/how-to-query-as-group-by-in-django">How to query as GROUP BY in django?</a></p>
  
  <p>And many more, but as a new user, anti-spam prevents me from adding them.</p>
  
  <p><strong>Thing's I've tried:</strong></p>
  
  <p>Chain:</p>
  
  <pre><code>listed_links = list(chain(topic, score))
  </code></pre>
  
  <p>Unfortunately, if I tried to add a sorted value this broke.</p>
  
  <p>Combining object lists:</p>
  
  <pre><code>topic = Topic.objects.all().values_list('user','id', 'title','slug', 'date_created', 'date_updated',)
  
  score = Vote.objects.values('object_id').annotate(total=Sum('vote')).order_by('-total')
  
  results = []
  
  for topic in topic:
  results.append(topic)
  
  for score in score:
  results.append(topic)
  </code></pre>
  
  <p>This resulted in all the objects I wanted in one list, but I could not figure out how to link <code>topic.id</code> to <code>score.object_id</code>.</p>
  
  <p>I've also tried inserting raw SQL, but I don't feel like I am doing it correctly, and could lead to SQL injection by a third party.</p>
  
  <p>I would love to share the results of this back to the django-voting project. Like I said, everything works as it should, except I cannot figure out how to sort by score desc.</p>
  
  <p>=============<strong>Voting</strong>========================</p>
  
  <pre><code>from django.contrib.contenttypes import generic
  
  from django.contrib.contenttypes.models import ContentType
  
  from django.contrib.auth.models import User
  
  from django.db import models
  
  from voting.managers import VoteManager
  
  from voting.VotedObjectsManager import VotedObjectsManager
  
      SCORES = (
      (+1, u'+1'),
      (-1, u'-1'),
  )
  
  class Vote(models.Model):
  
      """
      A vote on an object by a User.
      """
  
      user         = models.ForeignKey(User)
  
      content_type = models.ForeignKey(ContentType)
  
      object_id    = models.PositiveIntegerField()
  
      object       = generic.GenericForeignKey('content_type', 'object_id')
  
      vote         = models.SmallIntegerField(choices=SCORES)
  
      objects      = VoteManager()
  
  
      class Meta:
          db_table = 'votes'
          # One vote per user per object
          unique_together = (('user', 'content_type', 'object_id'),)
  
      def __unicode__(self):
          return u'%s: %s on %s' % (self.user, self.vote, self.object)
  
      def is_upvote(self):
          return self.vote == 1
  
      def is_downvote(self):
          return self.vote == -1
  </code></pre>
  
  <p>=============<strong>Topic Model</strong>========================</p>
  
  <pre><code>from django.db import models
  
  from datetime import datetime
  
  from tinymce import models as tinymce_models
  
  from django.forms import ModelForm
  
  from django.template.defaultfilters import slugify
  
  from tagging.fields import TagField
  
  from tagging.models import Tag
  
  from django.contrib.auth.models import User
  
  from django.utils.translation import ugettext_lazy as _
  
  from django.contrib.contenttypes.models import ContentType
  
  from django.contrib.contenttypes import generic
  
  from django.core import urlresolvers
  
      class Topic(models.Model):
  
      title           = models.CharField(max_length=50)
  
      slug            = models.SlugField(max_length=50, editable=False)
  
      topic         = tinymce_models.HTMLField()
  
      date_created    = models.DateTimeField(editable=False)
  
      date_updated    = models.DateTimeField(editable=False)
  
      tags            = TagField()
  
  
      def set_tags(self, tags):
          Tag.objects.update_tags(self, tags)    
  
      def __unicode__(self):
          return self.tags
  
      def __unicode__(self):
          return self.id
  
      def __unicode__(self):
          return self.title
  </code></pre>