def usage_for_model(self, model, counts=False, min_count=None, filters=None, extra=None): """ Obtain a list of tags associated with instances of the given Model class. If ``counts`` is True, a ``count`` attribute will be added to each tag, indicating how many times it has been used against the Model class in question. If ``min_count`` is given, only tags which have a ``count`` greater than or equal to ``min_count`` will be returned. Passing a value for ``min_count`` implies ``counts=True``. To limit the tags (and counts, if specified) returned to those used by a subset of the Model's instances, pass a dictionary of field lookups to be applied to the given Model as the ``filters`` argument. """ if extra is None: extra = {} if filters is None: filters = {} if not parse_lookup: # post-queryset-refactor (hand off to usage_for_queryset) queryset = model._default_manager.filter() for f in filters.items(): queryset.query.add_filter(f) usage = self.usage_for_queryset(queryset, counts, min_count, extra) else: # pre-queryset-refactor extra_joins = '' extra_criteria = '' params = [] if len(filters) > 0: joins, where, params = parse_lookup(filters.items(), model._meta) extra_joins = ' '.join([ '%s %s AS %s ON %s' % (join_type, table, alias, condition) for (alias, (table, join_type, condition)) in joins.items() ]) extra_criteria = 'AND %s' % (' AND '.join(where)) usage = self._get_usage(model, counts, min_count, extra_joins, extra_criteria, params, extra) return usage
def usage_for_model(self, model, counts=False, min_count=None, filters=None): """ Obtain a list of tags associated with instances of the given Model class. If ``counts`` is True, a ``count`` attribute will be added to each tag, indicating how many times it has been used against the Model class in question. If ``min_count`` is given, only tags which have a ``count`` greater than or equal to ``min_count`` will be returned. Passing a value for ``min_count`` implies ``counts=True``. To limit the tags (and counts, if specified) returned to those used by a subset of the Model's instances, pass a dictionary of field lookups to be applied to the given Model as the ``filters`` argument. """ if filters is None: filters = {} if not parse_lookup: # post-queryset-refactor (hand off to usage_for_queryset) queryset = model._default_manager.filter() for f in filters.items(): queryset.query.add_filter(f) usage = self.usage_for_queryset(queryset, counts, min_count) else: # pre-queryset-refactor extra_joins = "" extra_criteria = "" params = [] if len(filters) > 0: joins, where, params = parse_lookup(filters.items(), model._meta) extra_joins = " ".join( [ "%s %s AS %s ON %s" % (join_type, table, alias, condition) for (alias, (table, join_type, condition)) in joins.items() ] ) extra_criteria = "AND %s" % (" AND ".join(where)) usage = self._get_usage(model, counts, min_count, extra_joins, extra_criteria, params) return usage
def usage_for_model(self, Model, counts=False, min_count=None, filters=None): """ Obtain a list of tags associated with instances of the given Model. If ``counts`` is True, a ``count`` attribute will be added to each tag, indicating how many times it has been used against the Model in question. If ``min_count`` is given, only tags which have a ``count`` greater than or equal to ``min_count`` will be returned. Passing a value for ``min_count`` implies ``counts=True``. To limit the tags (and counts, if specified) returned to those used by a subset of the Model's instances, pass a dictionary of field lookups to be applied to the given Model as the ``filters`` argument. """ if filters is None: filters = {} if min_count is not None: counts = True model_table = backend.quote_name(Model._meta.db_table) model_pk = '%s.%s' % (model_table, backend.quote_name(Model._meta.pk.column)) query = """ SELECT DISTINCT %(tag)s.id, %(tag)s.name%(count_sql)s FROM %(tag)s INNER JOIN %(tagged_item)s ON %(tag)s.id = %(tagged_item)s.tag_id INNER JOIN %(model)s ON %(tagged_item)s.object_id = %(model_pk)s %%s WHERE %(tagged_item)s.content_type_id = %(content_type_id)s %%s GROUP BY %(tag)s.id, %(tag)s.name %%s ORDER BY %(tag)s.name ASC""" % { 'tag': backend.quote_name(self.model._meta.db_table), 'count_sql': counts and (', COUNT(%s)' % model_pk) or '', 'tagged_item': backend.quote_name( self._get_related_model_by_accessor('items')._meta.db_table), 'model': model_table, 'model_pk': model_pk, 'content_type_id': ContentType.objects.get_for_model(Model).id, } extra_joins = '' extra_criteria = '' min_count_sql = '' params = [] if len(filters) > 0: joins, where, params = parse_lookup(filters.items(), Model._meta) extra_joins = ' '.join([ '%s %s AS %s ON %s' % (join_type, table, alias, condition) for (alias, (table, join_type, condition)) in joins.items() ]) extra_criteria = 'AND %s' % (' AND '.join(where)) if min_count is not None: min_count_sql = 'HAVING COUNT(%s) >= %%s' % model_pk params.append(min_count) cursor = connection.cursor() cursor.execute(query % (extra_joins, extra_criteria, min_count_sql), params) tags = [] for row in cursor.fetchall(): t = self.model(*row[:2]) if counts: t.count = row[2] tags.append(t) return tags
def usage_for_model(self, model, counts=False, min_count=None, filters=None): """ Obtain a list of tags associated with instances of the given Model class. If ``counts`` is True, a ``count`` attribute will be added to each tag, indicating how many times it has been used against the Model class in question. If ``min_count`` is given, only tags which have a ``count`` greater than or equal to ``min_count`` will be returned. Passing a value for ``min_count`` implies ``counts=True``. To limit the tags (and counts, if specified) returned to those used by a subset of the Model's instances, pass a dictionary of field lookups to be applied to the given Model as the ``filters`` argument. """ if filters is None: filters = {} if min_count is not None: counts = True model_table = qn(model._meta.db_table) model_pk = '%s.%s' % (model_table, qn(model._meta.pk.column)) query = """ SELECT DISTINCT %(tag)s.id, %(tag)s.name%(count_sql)s FROM %(tag)s INNER JOIN %(tagged_item)s ON %(tag)s.id = %(tagged_item)s.tag_id INNER JOIN %(model)s ON %(tagged_item)s.object_id = %(model_pk)s %%s WHERE %(tagged_item)s.content_type_id = %(content_type_id)s %%s GROUP BY %(tag)s.id, %(tag)s.name %%s ORDER BY %(tag)s.name ASC""" % { 'tag': qn(self.model._meta.db_table), 'count_sql': counts and (', COUNT(%s)' % model_pk) or '', 'tagged_item': qn(self._get_related_model_by_accessor('items')._meta.db_table), 'model': model_table, 'model_pk': model_pk, 'content_type_id': ContentType.objects.get_for_model(model).pk, } extra_joins = '' extra_criteria = '' min_count_sql = '' params = [] if len(filters) > 0: joins, where, params = parse_lookup(filters.items(), model._meta) extra_joins = ' '.join(['%s %s AS %s ON %s' % (join_type, table, alias, condition) for (alias, (table, join_type, condition)) in joins.items()]) extra_criteria = 'AND %s' % (' AND '.join(where)) if min_count is not None: min_count_sql = 'HAVING COUNT(%s) >= %%s' % model_pk params.append(min_count) cursor = connection.cursor() cursor.execute(query % (extra_joins, extra_criteria, min_count_sql), params) tags = [] for row in cursor.fetchall(): t = self.model(*row[:2]) if counts: t.count = row[2] tags.append(t) return tags