def _get_content(instance_or_content): """ Given a model instance or a sequence *(content_type, object_id)* return a tuple *(content_type, object_id)*. """ try: object_id = instance_or_content.pk except AttributeError: return instance_or_content else: return (managers.get_content_type_for_model(type(instance_or_content)), object_id)
def _get_content(instance_or_content): """ Given a model instance or a sequence *(content_type, object_id)* return a tuple *(content_type, object_id)*. """ try: object_id = instance_or_content.pk except AttributeError: return instance_or_content else: return (managers.get_content_type_for_model(type(instance_or_content)), object_id)
def annotate_votes(queryset_or_model, key, user, score='score'): """ Annotate *queryset_or_model* with votes, in order to retreive from the database all vote values in bulk. The first argument *queryset_or_model* must be, of course, a queryset or a Django model object. The argument *key* is the score key. The votes are filtered using given *user*. For anonymous voters this functionality is unavailable. The score itself will be present in the attribute named *score* of each instance of the returned queryset. Usage example:: for article in annotate_votes(Article.objects.all(), 'main', myuser, score='myscore'): print 'your vote:', article.myscore """ # getting the queryset if isinstance(queryset_or_model, models.base.ModelBase): queryset = queryset_or_model.objects.all() else: queryset = queryset_or_model # preparing arguments for *extra* query opts = queryset.model._meta content_type = managers.get_content_type_for_model(queryset.model) mapping = { 'vote_table': Vote._meta.db_table, 'model_table': opts.db_table, 'model_pk_name': opts.pk.name, 'content_type_id': content_type.pk, } # building base query template = """ SELECT score FROM ${vote_table} WHERE ${vote_table}.object_id = ${model_table}.${model_pk_name} AND ${vote_table}.content_type_id = ${content_type_id} AND ${vote_table}.user_id = %s AND ${vote_table}.key = %s """ select = {score: string.Template(template).substitute(mapping)} return queryset.extra(select=select, select_params=[user.pk, key])
def annotate_votes(queryset_or_model, key, user, score='score'): """ Annotate *queryset_or_model* with votes, in order to retreive from the database all vote values in bulk. The first argument *queryset_or_model* must be, of course, a queryset or a Django model object. The argument *key* is the score key. The votes are filtered using given *user*. For anonymous voters this functionality is unavailable. The score itself will be present in the attribute named *score* of each instance of the returned queryset. Usage example:: for article in annotate_votes(Article.objects.all(), 'main', myuser, score='myscore'): print 'your vote:', article.myscore """ # getting the queryset if isinstance(queryset_or_model, models.base.ModelBase): queryset = queryset_or_model.objects.all() else: queryset = queryset_or_model # preparing arguments for *extra* query opts = queryset.model._meta content_type = managers.get_content_type_for_model(queryset.model) mapping = { 'vote_table': Vote._meta.db_table, 'model_table': opts.db_table, 'model_pk_name': opts.pk.name, 'content_type_id': content_type.pk, } # building base query template = """ SELECT score FROM ${vote_table} WHERE ${vote_table}.object_id = ${model_table}.${model_pk_name} AND ${vote_table}.content_type_id = ${content_type_id} AND ${vote_table}.user_id = %s AND ${vote_table}.key = %s """ select = {score: string.Template(template).substitute(mapping)} return queryset.extra(select=select, select_params=[user.pk, key])
def annotate_scores(queryset_or_model, key, **kwargs): """ Annotate *queryset_or_model* with scores, in order to retreive from the database all score values in bulk. The first argument *queryset_or_model* must be, of course, a queryset or a Django model object. The argument *key* is the score key. In *kwargs* it is possible to specify the values to retreive mapped to field names (it is up to you to avoid name clashes). You can annotate the queryset with the number of votes (*num_votes*), the average score (*average*) and the total sum of all votes (*total*). For example, the following call:: annotate_scores(Article.objects.all(), 'main', average='average', num_votes='num_votes') Will return a queryset of article and each article will have two new attached fields *average* and *num_votes*. Of course it is possible to sort the queryset by a score value, e.g.:: for article in annotate_scores(Article, 'by_staff', staff_avg='average', staff_num_votes='num_votes' ).order_by('-staff_avg', '-staff_num_votes'): print 'staff num votes:', article.staff_num_votes print 'staff average:', article.staff_avg """ # getting the queryset if isinstance(queryset_or_model, models.base.ModelBase): queryset = queryset_or_model.objects.all() else: queryset = queryset_or_model # annotations are done only if fields are requested if kwargs: # preparing arguments for *extra* query select = SortedDict() # not really needed (see below) select_params = [] opts = queryset.model._meta content_type = managers.get_content_type_for_model(queryset.model) mapping = { 'score_table': Score._meta.db_table, 'model_table': opts.db_table, 'model_pk_name': opts.pk.name, 'content_type_id': content_type.pk, } # building base query template = """ SELECT ${field_name} FROM ${score_table} WHERE ${score_table}.object_id = ${model_table}.${model_pk_name} AND ${score_table}.content_type_id = ${content_type_id} AND ${score_table}.key = %s """ template = string.Template(template).safe_substitute(mapping) # building one query for each requested field for alias, field_name in kwargs.items(): query = string.Template(template).substitute( {'field_name': field_name}) select[alias] = query # and that's why SortedDict are not really needed select_params.append(key) return queryset.extra(select=select, select_params=select_params) return queryset
def annotate_scores(queryset_or_model, key, **kwargs): """ Annotate *queryset_or_model* with scores, in order to retreive from the database all score values in bulk. The first argument *queryset_or_model* must be, of course, a queryset or a Django model object. The argument *key* is the score key. In *kwargs* it is possible to specify the values to retreive mapped to field names (it is up to you to avoid name clashes). You can annotate the queryset with the number of votes (*num_votes*), the average score (*average*) and the total sum of all votes (*total*). For example, the following call:: annotate_scores(Article.objects.all(), 'main', average='average', num_votes='num_votes') Will return a queryset of article and each article will have two new attached fields *average* and *num_votes*. Of course it is possible to sort the queryset by a score value, e.g.:: for article in annotate_scores(Article, 'by_staff', staff_avg='average', staff_num_votes='num_votes' ).order_by('-staff_avg', '-staff_num_votes'): print 'staff num votes:', article.staff_num_votes print 'staff average:', article.staff_avg """ # getting the queryset if isinstance(queryset_or_model, models.base.ModelBase): queryset = queryset_or_model.objects.all() else: queryset = queryset_or_model # annotations are done only if fields are requested if kwargs: # preparing arguments for *extra* query select = SortedDict() # not really needed (see below) select_params = [] opts = queryset.model._meta content_type = managers.get_content_type_for_model(queryset.model) mapping = { 'score_table': Score._meta.db_table, 'model_table': opts.db_table, 'model_pk_name': opts.pk.name, 'content_type_id': content_type.pk, } # building base query template = """ SELECT ${field_name} FROM ${score_table} WHERE ${score_table}.object_id = ${model_table}.${model_pk_name} AND ${score_table}.content_type_id = ${content_type_id} AND ${score_table}.key = %s """ template = string.Template(template).safe_substitute(mapping) # building one query for each requested field for alias, field_name in kwargs.items(): query = string.Template(template).substitute( {'field_name': field_name}) select[alias] = query # and that's why SortedDict are not really needed select_params.append(key) return queryset.extra(select=select, select_params=select_params) return queryset