2009-07-19 2 views
1

Есть ли способ упростить этот рабочий код? Этот код получает для объекта все разные типы голосования, есть 20 возможных и подсчитывает каждый тип. Я предпочитаю не писать raw sql, а использовать orm. Это немного сложнее, потому что я использую общий внешний ключ в модели.map raw sql to django 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) 

ответ

1

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

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

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

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

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

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

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

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

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

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

+0

Объект голосования использует ключевой ключ для ключей, я хочу иметь возможность проголосовать за любой объект. Я также добавлю код модели. – Stephan

+0

Предполагаю, вы расследовали внешние отношения? Они позволяют вам напрямую создавать нужный объект. Пример выглядит так, как будто может быть ответ. http://www.djangoproject.com/documentation/models/generic_relations/ – AlbertoPL

Смежные вопросы