if parse_lookup:
raise AttributeError("'TagManager.usage_for_queryset' is not compatible with pre-queryset-refactor versions of Django.")
- extra_joins = ' '.join(queryset.query.get_from_clause()[0][1:])
- where, params = queryset.query.where.as_sql()
+ if getattr(queryset.query, 'get_compiler', None):
+ # Django 1.2+
+ compiler = queryset.query.get_compiler(using='default')
+ extra_joins = ' '.join(compiler.get_from_clause()[0][1:])
+ where, params = queryset.query.where.as_sql(
+ compiler.quote_name_unless_alias, compiler.connection
+ )
+ else:
+ # Django pre-1.2
+ extra_joins = ' '.join(queryset.query.get_from_clause()[0][1:])
+ where, params = queryset.query.where.as_sql()
+
if where:
extra_criteria = 'AND %s' % where
else:
else:
return model._default_manager.none()
- def get_related(self, obj, queryset_or_model, num=None):
+ def get_related(self, obj, queryset_or_model, num=None, ignore_by_tag=None):
"""
Retrieve a list of instances of the specified model which share
tags with the model instance ``obj``, ordered by the number of
If ``num`` is given, a maximum of ``num`` instances will be
returned.
+
+ If ``ignore_by_tag`` is given, object tagged with it will be ignored.
"""
queryset, model = get_queryset_and_model(queryset_or_model)
model_table = qn(model._meta.db_table)
# instances for the same model.
query += """
AND related_tagged_item.object_id != %(tagged_item)s.object_id"""
+ if ignore_by_tag is not None:
+ query += """
+ AND NOT EXISTS (
+ SELECT * FROM %(tagged_item)s
+ WHERE %(tagged_item)s.object_id = %(model_pk)s
+ AND %(tagged_item)s.content_type_id = %(content_type_id)s
+ AND %(ignore_id)s = %(tagged_item)s.tag_id
+ )
+ """
query += """
GROUP BY %(model_pk)s
ORDER BY %(count)s DESC
'content_type_id': content_type.pk,
'related_content_type_id': related_content_type.pk,
'limit_offset': num is not None and connection.ops.limit_offset_sql(num) or '',
+ 'ignore_id': ignore_by_tag.id if ignore_by_tag else None,
}
cursor = connection.cursor()