def filter(self, **kwargs): """ The *kwargs* can be: - user: Django user object or pk - instance: a Django model instance - content_type: a Django ContentType instance or pk - model: a Django model - key: the bookmark key to use - reversed: reverse the order of results """ order = '-created_at' if kwargs.pop('reversed', False) else 'created_at' if 'instance' in kwargs: instance = kwargs.pop('instance') kwargs.update({ 'content_type': utils.get_content_type_for_model(instance), 'object_id': instance.pk, }) elif 'model' in kwargs: model = kwargs.pop('model') kwargs['content_type'] = utils.get_content_type_for_model(model) if 'user' in kwargs: queryset = self.get_model().objects.filter_with_contents(**kwargs) else: queryset = self.get_model().objects.filter(**kwargs) return queryset.order_by(order)
def filter_for(self, content_object_or_model, **kwargs): """ Return all the instances related to *content_object_or_model* and matching *kwargs*. The argument *content_object_or_model* can be both a model instance or a model class. """ if isinstance(content_object_or_model, models.base.ModelBase): lookups = {'content_type': utils.get_content_type_for_model( content_object_or_model)} else: lookups = { 'content_type': utils.get_content_type_for_model( type(content_object_or_model)), 'object_id': content_object_or_model.pk, } lookups.update(kwargs) return self.filter(**lookups)
def remove_all_for(self, content_object): """ Remove all bookmarks for the given model instance. The application uses this whenever a bookmarkable model instance is deleted, in order to mantain the integrity of the bookmarks table. """ content_type = utils.get_content_type_for_model(type(content_object)) self.filter(content_type=content_type, object_id=content_object.id).delete()
def get_for(self, content_object, key, **kwargs): """ Return the instance related to *content_object* and matching *kwargs*. Return None if a bookmark is not found. """ content_type = utils.get_content_type_for_model(type(content_object)) try: return self.get(key=key, content_type=content_type, object_id=content_object.pk, **kwargs) except self.model.DoesNotExist: return None
def add(self, user, content_object, key): """ Add a bookmark, given the user, the model instance and the key. Raise a *Bookmark.AlreadyExists* exception if that kind of bookmark is present in the db. """ content_type = utils.get_content_type_for_model(type(content_object)) try: return self.create(user=user, content_type=content_type, object_id=content_object.pk, key=key) except Exception: # TODO: IntegrityError? raise exceptions.AlreadyExists
def remove(self, user, content_object, key): """ Remove a bookmark, given the user, the model instance and the key. Raise a *Bookmark.DoesNotExist* exception if that kind of bookmark is not present in the db. """ content_type = utils.get_content_type_for_model(type(content_object)) try: bookmark = self.get(user=user, content_type=content_type, object_id=content_object.pk, key=key) except self.model.DoesNotExist: raise exceptions.DoesNotExist bookmark.delete() return bookmark
def annotate_bookmarks(queryset_or_model, key, user, attr='is_bookmarked'): """ Annotate *queryset_or_model* with bookmarks, in order to retreive from the database all bookmark 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 bookmark key. The bookmarks are filtered using given *user*. A boolean is inserted in an attr named *attr* (default='is_bookmarked') of each object in the generated queryset. Usage example:: for article in annotate_bookmarks(Article.objects.all(), 'favourite', myuser, attr='has_a_bookmark'): if article.has_a_bookmark: print u"User %s likes article %s" (myuser, article) """ from bookmarks import utils # 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 = utils.get_content_type_for_model(queryset.model) mapping = { 'bookmark_table': Bookmark._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 id FROM ${bookmark_table} WHERE ${bookmark_table}.object_id = ${model_table}.${model_pk_name} AND ${bookmark_table}.content_type_id = ${content_type_id} AND ${bookmark_table}.user_id = %s AND ${bookmark_table}.key = %s """ select = {attr: string.Template(template).substitute(mapping)} return queryset.extra(select=select, select_params=[user.pk, key])
def _get_content_type_id(self, instance): return utils.get_content_type_for_model(instance).id