0

With this models:

class Vine(models.Model):
   autor = models.ForeignKey(Viner,related_name='autor')
   titulo = models.CharField(max_length=450)
   estado = models.CharField(choices=ESTADOS_VINE, max_length=30)
   objects = models.Manager()
   custom_object = managers.VineManager()

and the model for the votes

class Voto(models.Model):
   user = models.ForeignKey(MyUser)
   submit_date = models.DateTimeField(auto_now_add=True)
   vine = models.ForeignKey(Vine)
   valoracion = models.BooleanField(default=False)

and the class for the Favorites (This is working fine yet)

class Favorito(models.Model):
   date = models.DateTimeField(auto_now_add=True)
   user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='favoritos')

I have this 'query' in Django.

vines = Vine.custom_object.filter(estado=2).\
            annotate(favoritosCount=Count('favoritos', distinct=True)).\
            filter(voto__valoracion=False).annotate(disLikesCount=Count('voto',      distinct=True))\
            .annotate(likesCount=Count('voto', distinct=True)).filter(voto__valoracion=True)

But the second filter is not working because of the first.

Basically what I want is to get the sum of 'positive votes' - 'negative votes' as a field and order by it.

Could anyone please help me?

Thank you in advance

Miki Torandell
  • 163
  • 1
  • 11
  • 1
    Show us your models. – danielcorreia Sep 18 '14 at 00:00
  • Excluding the _Count_, that query is pretty much the same as doing `Vine.custom_object.filter(estado=2, voto__valoracion=False, voto_valoracion=True)` which doesn't work like you seem to want. You may want to read the docs about [chaining filters](https://docs.djangoproject.com/en/dev/topics/db/queries/#chaining-filters). – danielcorreia Sep 18 '14 at 00:01
  • Yes, if we see the models it'll be easier. – Jonathan Sep 18 '14 at 12:26
  • Hi @danielcorreia, I have just updated the question with my models. May it help? – Miki Torandell Sep 21 '14 at 09:41

1 Answers1

0

AFAIK you can't do that query with the ORM. You might be able to do it with a raw query.

I think It's easier if you add a count field to your Vine model and order by it. Then update that count field every time there's a new Voto.

Something like this:

from django.db.models import F

class Vine(models.Model):
    ...
    votos = models.IntegerField()

    class Meta:
        ordering = ('votos',)


class Voto(models.Model):
    ...
    def save(self):
        """When saving new Voto instance, update related Vine."""
        if not self.pk:
             new_vote = 1 if self.valoracion else -1
             self.vine.update(votos=F('votos') + new_vote)
        return super(Voto, self).save()

PS: If you want to know more about that F expression.

danielcorreia
  • 2,108
  • 2
  • 24
  • 36