сопоставить raw sql с django orm - PullRequest
1 голос
/ 20 июля 2009

Есть ли способ упростить этот рабочий код? Этот код получает для объекта все различные типы голосования, их около 20, и считает каждый тип. Я предпочитаю не писать raw sql, а использовать orm. Это немного сложнее, потому что я использую общий внешний ключ в модели.

def get_object_votes(self, obj):
    """ 
    Get a dictionary mapping vote to votecount
    """
    ctype = ContentType.objects.get_for_model(obj)

    cursor = connection.cursor()
    cursor.execute("""
       SELECT v.vote , COUNT(*)
       FROM votes v
       WHERE %d = v.object_id AND %d = v.content_type_id
       GROUP BY 1
       ORDER BY 1 """ % ( obj.id, ctype.id )
    )
    votes = {}

    for row in cursor.fetchall():
       votes[row[0]] = row[1]

    return votes

Модели, использующие

class Vote(models.Model):
    user = models.ForeignKey(User)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    payload = generic.GenericForeignKey('content_type', 'object_id')

    vote = models.IntegerField(choices = possible_votes.items() )


class Issue(models.Model):
    title = models.CharField( blank=True, max_length=200)

Ответы [ 2 ]

1 голос
/ 20 июля 2009

Код ниже сделал трюк для меня!

def get_object_votes(self, obj, all=False):
    """
    Get a dictionary mapping vote to votecount
    """
    object_id = obj._get_pk_val()
    ctype = ContentType.objects.get_for_model(obj)
    queryset = self.filter(content_type=ctype, object_id=object_id)

    if not all:
        queryset = queryset.filter(is_archived=False) # only pick active votes

    queryset = queryset.values('vote')
    queryset = queryset.annotate(vcount=Count("vote")).order_by()

    votes = {}

    for count in queryset:
        votes[count['vote']] = count['vcount']

    return votes
0 голосов
/ 20 июля 2009

Да, обязательно используйте ORM. То, что вы действительно должны делать, это в вашей модели:

class Obj(models.Model):
    #whatever the object has

class Vote(models.Model):
    obj = models.ForeignKey(Obj) #this ties a vote to its object

Затем, чтобы получить все голоса от объекта, включите эти вызовы Django в одну из ваших функций просмотра:

obj = Obj.objects.get(id=#the id)
votes = obj.vote_set.all()

Отсюда довольно легко увидеть, как их подсчитать (получить длину списка, называемого голосами).

Я рекомендую почитать об отношениях многие-к-одному из документации, это очень удобно.

http://www.djangoproject.com/documentation/models/many_to_one/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...