2009-07-19 8 views
1

Gibt es eine Möglichkeit, diesen Arbeitscode zu vereinfachen? Dieser Code erhält für ein Objekt alle verschiedenen Stimmarten, es sind 20 möglich, und zählt jeden Typ. Ich bevorzuge es, nicht rohe SQL zu schreiben, sondern die ORM. Es ist ein bisschen komplizierter, weil ich generischen Fremdschlüssel im Modell verwende.Karte rohe SQL zu 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 

Die Modelle im

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) 

Antwort

1

Der Code hat Unterhalb der Trick für mich!

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

Ja, auf jeden Fall die ORM verwenden. Was sollten Sie wirklich tun, ist dies in Ihrem Modell:

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

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

Dann von einem Objekt alle Stimmen zu bekommen, müssen diese Django nennt in einem Ihrer Ansicht Funktionen sein:

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

Aus Da ist es ziemlich einfach zu sehen, wie man sie zählen kann (die Länge der Liste nennt man Votes).

Ich empfehle das Lesen über viele-zu-eins-Beziehungen aus der Dokumentation, es ist ziemlich praktisch.

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

+0

Das Vote-Objekt verwendet einen generierenden Schlüssel, ich möchte über jedes Objekt abstimmen können. Ich werde den Modellcode auch hinzufügen. – Stephan

+0

Ich nehme an, Sie haben ausländische Beziehungen untersucht? Mit ihnen können Sie das gewünschte Objekt direkt erstellen. Das Beispiel sieht möglicherweise wie die Antwort aus. http://www.djangoproject.com/documentation/models/generic_relations/ – AlbertoPL