Пример #1
0
    def testBasicTagging(self):
        dead = Parrot.objects.create(state='dead')
        Tag.objects.update_tags(dead, 'foo,bar,"ter"')

        self.assertListsEqual(get_tag_list('bar foo ter'),
                              Tag.objects.get_for_object(dead))

        Tag.objects.update_tags(dead, '"foo" bar "baz"')
        self.assertListsEqual(get_tag_list('bar baz foo'),
                              Tag.objects.get_for_object(dead))

        Tag.objects.add_tag(dead, 'foo')
        self.assertListsEqual(get_tag_list('bar baz foo'),
                              Tag.objects.get_for_object(dead))

        Tag.objects.add_tag(dead, 'zip')
        self.assertListsEqual(get_tag_list('bar baz foo zip'),
                              Tag.objects.get_for_object(dead))

        self.assertRaises(AttributeError, Tag.objects.add_tag, dead, '    ')
        self.assertRaises(AttributeError, Tag.objects.add_tag, dead, 'one two')

        Tag.objects.update_tags(dead, 'ŠĐĆŽćžšđ')
        self.assertEqual(
            '[<Tag: \xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91>]',
            repr(Tag.objects.get_for_object(dead)))

        Tag.objects.update_tags(dead, None)
        self.assertListsEqual([], Tag.objects.get_for_object(dead))
Пример #2
0
    def testBasicTagging(self):
        dead = Parrot.objects.create(state='dead')
        Tag.objects.update_tags(dead, 'foo,bar,"ter"')

        self.assertListsEqual(get_tag_list('bar foo ter'), Tag.objects.get_for_object(dead))

        Tag.objects.update_tags(dead, '"foo" bar "baz"')
        self.assertListsEqual(get_tag_list('bar baz foo'), Tag.objects.get_for_object(dead))

        Tag.objects.add_tag(dead, 'foo')
        self.assertListsEqual(get_tag_list('bar baz foo'), Tag.objects.get_for_object(dead))

        Tag.objects.add_tag(dead, 'zip')
        self.assertListsEqual(get_tag_list('bar baz foo zip'), Tag.objects.get_for_object(dead))

        self.assertRaises(AttributeError, Tag.objects.add_tag, dead, '    ')
        self.assertRaises(AttributeError, Tag.objects.add_tag, dead, 'one two')

        Tag.objects.update_tags(dead, 'ŠĐĆŽćžšđ')
        self.assertEqual(
            '[<Tag: \xc5\xa0\xc4\x90\xc4\x86\xc5\xbd\xc4\x87\xc5\xbe\xc5\xa1\xc4\x91>]',
            repr(Tag.objects.get_for_object(dead)))

        Tag.objects.update_tags(dead, None)
        self.assertListsEqual([], Tag.objects.get_for_object(dead))
Пример #3
0
 def relate(self, tags, relation_type='~', related_tags=[], force_create=False):
     '''
     Relates each tag in a list of tags with each tag in a list of related_tags
     with the given relation type. Tag lists can be Tag instances or strings.
     Relations are created symmetrically. If force_create = True, tags are 
     created from string if they do not already exist. If just a list of tags are 
     given, it calls relate_all() to relate them with each other using '~' relation.
     Updates existing relations if needed.
     '''
     #TODO: WTF
     tags = get_tag_list(tags)
     if related_tags == []:
         self.relate_all(tags)
     else:
         related_tags = get_tag_list(related_tags)
         for tag in tags:
             tag = get_tag(tag)
             if tag and tag.is_valid:
                     for related_tag in related_tags:
                         related_tag = get_tag(related_tag)
                         if related_tag and related_tag.is_valid:
                                 if tag != related_tag:
                                     rel, c = RelatedTag.objects.get_or_create(tag=tag, related_tag=related_tag,
                                                                               defaults={'relation_type': relation_type,
                                                                                         'count': 1})
                                     if not c:
                                         rel.count += 1
                                         # check if the existing relation is correct
                                         if rel.relation_type != relation_type:
                                             rel.relation_type = relation_type
                                         rel.save()
Пример #4
0
 def test_with_invalid_input_mix_of_string_and_instance(self):
     try:
         get_tag_list(["cheese", self.toast])
     except ValueError, ve:
         self.assertEquals(
             str(ve), "If a list or tuple of tags is provided, they must all be tag names, Tag objects or Tag ids."
         )
Пример #5
0
    def testForcingTagsToLowercase(self):
        settings.FORCE_LOWERCASE_TAGS = True

        dead = Parrot.objects.create(state='dead')
        Tag.objects.update_tags(dead, 'foO bAr Ter')
        self.assertListsEqual(get_tag_list('bar foo ter'),
                              Tag.objects.get_for_object(dead))

        Tag.objects.update_tags(dead, 'foO bAr baZ')
        self.assertListsEqual(get_tag_list('bar baz foo'),
                              Tag.objects.get_for_object(dead))

        Tag.objects.add_tag(dead, 'FOO')
        self.assertListsEqual(get_tag_list('bar baz foo'),
                              Tag.objects.get_for_object(dead))

        Tag.objects.add_tag(dead, 'Zip')
        self.assertListsEqual(get_tag_list('bar baz foo zip'),
                              Tag.objects.get_for_object(dead))

        Tag.objects.update_tags(dead, None)
        f1 = FormTest.objects.create(tags=u'test3 test2 test1')
        f1.tags = u'TEST5'
        f1.save()
        self.assertListsEqual(get_tag_list('test5'),
                              Tag.objects.get_for_object(f1))
        self.assertEqual(u'test5', f1.tags)
Пример #6
0
 def test_with_invalid_input_mix_of_string_and_instance(self):
     try:
         get_tag_list(['cheese', self.toast])
     except ValueError, ve:
         self.assertEquals(
             str(ve),
             'If a list or tuple of tags is provided, they must all be tag names, Tag objects or Tag ids.'
         )
Пример #7
0
 def testUsingAModelsTagField(self):
     f1 = FormTest.objects.create(tags=u'test3 test2 test1')
     self.assertListsEqual(get_tag_list('test1 test2 test3'), Tag.objects.get_for_object(f1))
     f1.tags = u'test4'
     f1.save()
     self.assertListsEqual(get_tag_list('test4'), Tag.objects.get_for_object(f1))
     f1.tags = ''
     f1.save()
     self.assertListsEqual([], Tag.objects.get_for_object(f1))
Пример #8
0
 def test_with_invalid_input(self):
     try:
         get_tag_list(29)
     except ValueError as ve:
         self.assertEqual(str(ve), 'The tag input given was invalid.')
     except Exception as e:
         raise self.failureException('the wrong type of exception was raised: type [%s] value [%s]' %\
             (str(type(e)), str(e)))
     else:
         raise self.failureException('a ValueError exception was supposed to be raised!')
Пример #9
0
 def test_with_invalid_input(self):
     try:
         get_tag_list(29)
     except ValueError as ve:
         self.assertEqual(str(ve), 'The tag input given was invalid.')
     except Exception as e:
         print('--', e)
         raise self.failureException('the wrong type of exception was raised: type [%s] value [%s]' % \
             (str(type(e)), str(e)))
     else:
         raise self.failureException('a ValueError exception was supposed to be raised!')
Пример #10
0
 def test_with_invalid_input_mix_of_string_and_instance(self):
     try:
         get_tag_list(['cheese', self.toast])
     except ValueError as ve:
         self.assertEqual(str(ve),
             'If a list or tuple of tags is provided, they must all be tag names, Tag objects or Tag ids.')
     except Exception as e:
         raise self.failureException('the wrong type of exception was raised: type [%s] value [%]' %\
             (str(type(e)), str(e)))
     else:
         raise self.failureException('a ValueError exception was supposed to be raised!')
Пример #11
0
 def testUsingAModelsTagField(self):
     f1 = FormTest.objects.create(tags=u'test3 test2 test1')
     self.assertListsEqual(get_tag_list('test1 test2 test3'),
                           Tag.objects.get_for_object(f1))
     f1.tags = u'test4'
     f1.save()
     self.assertListsEqual(get_tag_list('test4'),
                           Tag.objects.get_for_object(f1))
     f1.tags = ''
     f1.save()
     self.assertListsEqual([], Tag.objects.get_for_object(f1))
Пример #12
0
 def test_with_invalid_input_mix_of_string_and_instance(self):
     try:
         get_tag_list(['cheese', self.toast])
     except ValueError as ve:
         self.assertEqual(str(ve),
             'If a list or tuple of tags is provided, they must all be tag names, Tag objects or Tag ids.')
     except Exception as e:
         raise self.failureException('the wrong type of exception was raised: type [%s] value [%]' % \
             (str(type(e)), str(e)))
     else:
         raise self.failureException('a ValueError exception was supposed to be raised!')
Пример #13
0
 def test_with_invalid_input(self):
     try:
         get_tag_list(29)
     except ValueError as ve:
         self.assertEqual(str(ve), "The tag input given was invalid.")
     except Exception as e:
         print("--", e)
         raise self.failureException(
             "the wrong type of exception was raised: " "type [%s] value [%s]" % (str(type(e)), str(e))
         )
     else:
         raise self.failureException("a ValueError exception was supposed to be raised!")
Пример #14
0
 def testNormalisedTagListInput(self):
     cheese = Tag.objects.create(name='cheese')
     toast = Tag.objects.create(name='toast')
     self.assertListsEqual([cheese], get_tag_list(cheese))
     self.assertListsEqual([cheese, toast], get_tag_list('cheese toast'))
     self.assertListsEqual([cheese, toast], get_tag_list('cheese,toast'))
     self.assertListsEqual([], get_tag_list([]))
     self.assertListsEqual([cheese, toast], get_tag_list(['cheese', 'toast']))
     self.assertListsEqual([cheese, toast], get_tag_list([cheese.id, toast.id]))
     self.assertListsEqual([cheese, toast], get_tag_list(['cheese', 'toast', 'ŠĐĆŽćžšđ']))
     self.assertListsEqual([cheese, toast], get_tag_list([cheese, toast]))
     self.assertEqual((cheese, toast), get_tag_list((cheese, toast)))
     self.assertListsEqual([cheese, toast], get_tag_list(Tag.objects.filter(name__in=['cheese', 'toast'])))
     self.assertRaises(ValueError, get_tag_list, ['cheese', toast])
     self.assertRaises(ValueError, get_tag_list, 29)
Пример #15
0
    def related_for_model(self, tags, model, counts=False, min_count=None, label=None):
        """
        Obtain a list of tags related to a given list of tags - that
        is, other tags used by items which have all the given tags.

        If ``counts`` is True, a ``count`` attribute will be added to
        each tag, indicating the number of items which have it in
        addition to the given list of tags.

        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``.
        """
        ## Nonrel requires two (maybe three) queries and in-memory aggregation and sorting

        ## (1) grab all of the object_ids that point to the specified tags, for the model
        object_ids = TaggedItem.objects._get_intersection_object_ids(model, tags)

        ## (2) grab all of the TaggedItems that point to the same objects
        content_type = ContentType.objects.get_for_model(model)
        related = TaggedItem._default_manager.filter(object_id__in=object_ids, 
                                                     content_type=content_type)

        ## if there are no related TaggedItems at all, then there are no related tags
        if len(list(related)) == 0: ## TODO: django-nonrel len() bug
            return []

        ## (3) Simulate SQL aggregation in memory, and exclude the original tags.
        exclude_ids = set()
        for tag in get_tag_list(tags): #this may, or may not, execute an additional query
            exclude_ids.add(tag.id)
        return self._package_and_sort(related, counts, min_count, exclude_ids)
Пример #16
0
def edit_product(request, pid):
    prod = Product.objects.get(pk=pid)
    if request.method == 'POST':
        form = ProductForm(request.POST, instance=prod)
        if form.is_valid():
            form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            prod.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Product updated successfully.',
                                 extra_tags='alert-success')
            return HttpResponseRedirect(reverse('view_product', args=(pid, )))
    else:
        form = ProductForm(instance=prod,
                           initial={
                               'auth_users':
                               prod.authorized_users.all(),
                               'tags':
                               get_tag_list(Tag.objects.get_for_object(prod))
                           })
    add_breadcrumb(parent=prod, title="Edit", top_level=False, request=request)

    return render(request, 'dojo/edit_product.html', {
        'form': form,
        'product': prod,
    })
Пример #17
0
def edit_object(request, pid, ttid):
    object = Objects.objects.get(pk=ttid)

    if request.method == 'POST':
        tform = ObjectSettingsForm(request.POST, instance=object)
        if tform.is_valid():
            tform.save()

            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            object.tags = t

            messages.add_message(
                request,
                messages.SUCCESS,
                'Tool Product Configuration Successfully Updated.',
                extra_tags='alert-success')
            return HttpResponseRedirect(reverse('view_objects', args=(pid, )))
    else:
        tform = ObjectSettingsForm(
            instance=object,
            initial={'tags': get_tag_list(Tag.objects.get_for_object(object))})

    tform.initial['tags'] = [tag.name for tag in object.tags]
    add_breadcrumb(title="Edit Tracked Files",
                   top_level=False,
                   request=request)
    return render(request, 'dojo/edit_object.html', {
        'tform': tform,
    })
Пример #18
0
 def render(self, request, place, content, context, *args, **kwargs):
     if content and content.tags:
         content_tags = [i.name for i in get_tag_list(content.tags)]
         taglist = ITag.objects.filter(name__in=content_tags)
         return self.render_block(request, template_name='itags/blocks/content_tags.html',
                                  context={'taglist': taglist})
     return ''
Пример #19
0
def edit_object(request, pid, ttid):
    object = Objects.objects.get(pk=ttid)

    if request.method == 'POST':
        tform = ObjectSettingsForm(request.POST, instance=object)
        if tform.is_valid():
            tform.save()

            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            object.tags = t

            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Tool Product Configuration Successfully Updated.',
                                 extra_tags='alert-success')
            return HttpResponseRedirect(reverse('view_objects', args=(pid,)))
    else:
        tform = ObjectSettingsForm(instance=object,
        initial={'tags': get_tag_list(Tag.objects.get_for_object(object))})

    tform.initial['tags'] = [tag.name for tag in object.tags]
    add_breadcrumb(title="Edit Tracked Files", top_level=False, request=request)
    return render(request,
                  'dojo/edit_object.html',
                  {
                      'tform': tform,
                  })
Пример #20
0
    def get_by_model(self, queryset_or_model, tags):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with a given tag or list of tags.
        """
        tags = get_tag_list(tags)
        tag_count = len(tags)
        if tag_count == 0:
            # No existing tags were given
            queryset, model = get_queryset_and_model(queryset_or_model)
            return model._default_manager.none()
        elif tag_count == 1:
            # Optimisation for single tag - fall through to the simpler
            # query below.
            tag = tags[0]
        else:
            return self.get_intersection_by_model(queryset_or_model, tags)

        queryset, model = get_queryset_and_model(queryset_or_model)
        content_type = ContentType.objects.get_for_model(model)
        opts = self.model._meta
        tagged_item_table = qn(opts.db_table)
        return queryset.extra(
            tables=[opts.db_table],
            where=[
                '%s.content_type_id = %%s' % tagged_item_table,
                '%s.tag_id = %%s' % tagged_item_table,
                '%s.%s = %s.object_id' % (qn(model._meta.db_table),
                                          qn(model._meta.pk.column),
                                          tagged_item_table)
            ],
            params=[content_type.pk, tag.pk],
        )
Пример #21
0
def tag_search(request, tag, page=1, paginate_by=10, rtemplate="contacts/tag_results.html"):
    qstagquery = tagutils.get_tag_list(tag)
    taggedcontacts = TaggedItem.objects.get_by_model(Contact, [tag.name for tag in qstagquery])
    qscontacts = Contact.objects.filter(id__in = [c.id for c in taggedcontacts])
    request.session['searchresults'] = qscontacts

    return HttpResponseRedirect(reverse('contacts-searchresults'))
Пример #22
0
    def get_by_model(self, queryset_or_model, tags):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with a given tag or list of tags.
        """
        tags = get_tag_list(tags)
        tag_count = len(tags)
        if tag_count == 0:
            # No existing tags were given
            queryset, model = get_queryset_and_model(queryset_or_model)
            return model._default_manager.none()
        elif tag_count == 1:
            # Optimisation for single tag - fall through to the simpler
            # query below.
            tag = tags[0]
        else:
            return self.get_intersection_by_model(queryset_or_model, tags)

        queryset, model = get_queryset_and_model(queryset_or_model)
        content_type = ContentType.objects.get_for_model(model)
        opts = self.model._meta
        tagged_item_table = qn(opts.db_table)
        return queryset.extra(
            tables=[opts.db_table],
            where=[
                '%s.content_type_id = %%s' % tagged_item_table,
                '%s.tag_id = %%s' % tagged_item_table,
                '%s.%s = %s.object_id' %
                (qn(model._meta.db_table), qn(
                    model._meta.pk.column), tagged_item_table)
            ],
            params=[content_type.pk, tag.pk],
        )
Пример #23
0
    def get_union_by_model(self, queryset_or_model, tags):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with *any* of the given list of tags.
        """
        tags = get_tag_list(tags)
        tag_count = len(tags)
        queryset, model = get_queryset_and_model(queryset_or_model)
        model_table = qn(model._meta.db_table)
        # This query selects the ids of all objects which have any of
        # the given tags.
        query = """
        SELECT %(model_pk)s
        FROM %(model)s, %(tagged_item)s
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
          AND %(model_pk)s = %(tagged_item)s.object_id
        GROUP BY %(model_pk)s""" % {
            'model_pk': '%s.%s' % (model_table, qn(model._meta.pk.column)),
            'model': model_table,
            'tagged_item': qn(self.model._meta.db_table),
            'content_type_id': ContentType.objects.get_for_model(model).pk,
            'tag_id_placeholders': ','.join(['%s'] * tag_count),
        }

        cursor = connection.cursor()
        cursor.execute(query, [tag.pk for tag in tags])
        object_ids = [row[0] for row in cursor.fetchall()]
        if len(object_ids) > 0:
            return queryset.filter(pk__in=object_ids)
        else:
            return model._default_manager.none()
Пример #24
0
def edit_product(request, pid):
    prod = Product.objects.get(pk=pid)
    jira_enabled = True
    jira_inst = None
    try:
        jira_inst = JIRA_PKey.objects.get(product=prod)
    except:
        jira_enabled = False
        pass
    if request.method == 'POST':
        form = ProductForm(request.POST, instance=prod)
        if form.is_valid():
            form.save()
            tags = request.POST.getlist('tags')
            t = ", ".join(tags)
            prod.tags = t
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Product updated successfully.',
                                 extra_tags='alert-success')
            if hasattr(settings, 'ENABLE_JIRA'):
                if settings.ENABLE_JIRA:
                    if jira_enabled:
                        jform = JIRAPKeyForm(request.POST, instance=jira_inst)
                    else:
                        jform = JIRAPKeyForm(request.POST)
                        new_conf = jform.save(commit=False)
                        new_conf.product_id = pid
                        new_conf.save()
                        messages.add_message(
                            request,
                            messages.SUCCESS,
                            'JIRA information updated successfully.',
                            extra_tags='alert-success')

            return HttpResponseRedirect(reverse('view_product', args=(pid, )))
    else:
        form = ProductForm(instance=prod,
                           initial={
                               'auth_users':
                               prod.authorized_users.all(),
                               'tags':
                               get_tag_list(Tag.objects.get_for_object(prod))
                           })
        if hasattr(settings, 'ENABLE_JIRA'):
            if settings.ENABLE_JIRA:
                if jira_enabled:
                    jform = JIRAPKeyForm(instance=jira_inst)
                else:
                    jform = JIRAPKeyForm()
        else:
            jform = None
    add_breadcrumb(parent=prod, title="Edit", top_level=False, request=request)

    return render(request, 'dojo/edit_product.html', {
        'form': form,
        'jform': jform,
        'product': prod,
    })
Пример #25
0
    def related_for_model(self, tags, model, counts=False, min_count=None,
                          wildcard=None, default_namespace=None):
        """
        Obtain a list of tags related to a given list of tags - that
        is, other tags used by items which have all the given tags.

        If ``counts`` is True, a ``count`` attribute will be added to
        each tag, indicating the number of items which have it in
        addition to the given list of tags.

        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``.
        """
        if min_count is not None: counts = True
        tags = get_tag_list(tags,
            wildcard=wildcard, default_namespace=default_namespace)
        tag_count = len(tags)
        tagged_item_table = qn(TaggedItem._meta.db_table)
        query = """
        SELECT %(tag)s.id, %(tag)s.namespace, %(tag)s.name, %(tag)s.value%(count_sql)s
        FROM %(tagged_item)s INNER JOIN %(tag)s ON %(tagged_item)s.tag_id = %(tag)s.id
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.object_id IN
          (
              SELECT %(tagged_item)s.object_id
              FROM %(tagged_item)s, %(tag)s
              WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
                AND %(tag)s.id = %(tagged_item)s.tag_id
                AND %(tag)s.id IN (%(tag_id_placeholders)s)
              GROUP BY %(tagged_item)s.object_id
              HAVING COUNT(%(tagged_item)s.object_id) = %(tag_count)s
          )
          AND %(tag)s.id NOT IN (%(tag_id_placeholders)s)
        GROUP BY %(tag)s.id, %(tag)s.namespace, %(tag)s.name, %(tag)s.value
        %(min_count_sql)s
        ORDER BY %(tag)s.name ASC""" % {
            'tag': qn(self.model._meta.db_table),
            'count_sql': counts and ', COUNT(%s.object_id)' % tagged_item_table or '',
            'tagged_item': tagged_item_table,
            'content_type_id': ContentType.objects.get_for_model(model).pk,
            'tag_id_placeholders': ','.join(['%s'] * tag_count),
            'tag_count': tag_count,
            'min_count_sql': min_count is not None and ('HAVING COUNT(%s.object_id) >= %%s' % tagged_item_table) or '',
        }

        params = [tag.pk for tag in tags] * 2
        if min_count is not None:
            params.append(min_count)

        cursor = connection.cursor()
        cursor.execute(query, params)
        related = []
        for row in cursor.fetchall():
            tag = self.model(*row[:4])
            if counts is True:
                tag.count = row[4]
            related.append(tag)
        return related
Пример #26
0
    def related_for_model(self, tags, model, counts=False, min_count=None):
        """
        Obtain a list of tags related to a given list of tags - that
        is, other tags used by items which have all the given tags.

        If ``counts`` is True, a ``count`` attribute will be added to
        each tag, indicating the number of items which have it in
        addition to the given list of tags.

        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``.
        """
        if min_count is not None:
            counts = True
        tags = get_tag_list(tags)
        tag_count = len(tags)
        tagged_item_table = qn(TaggedItem._meta.db_table)
        query = """
        SELECT %(tag)s.id%(count_sql)s
        FROM %(tagged_item)s INNER JOIN %(tag)s ON %(tagged_item)s.tag_id = %(tag)s.id
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.object_id IN
          (
              SELECT %(tagged_item)s.object_id
              FROM %(tagged_item)s, %(tag)s
              WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
                AND %(tag)s.id = %(tagged_item)s.tag_id
                AND %(tag)s.id IN (%(tag_id_placeholders)s)
              GROUP BY %(tagged_item)s.object_id
              HAVING COUNT(%(tagged_item)s.object_id) = %(tag_count)s
          )
          AND %(tag)s.id NOT IN (%(tag_id_placeholders)s)
        GROUP BY %(tag)s.id
        %(min_count_sql)s""" % {
            "tag": qn(self.model._meta.db_table),
            "count_sql": counts and ", COUNT(%s.object_id)" % tagged_item_table or "",
            "tagged_item": tagged_item_table,
            "content_type_id": ContentType.objects.get_for_model(model).pk,
            "tag_id_placeholders": ",".join(["%s"] * tag_count),
            "tag_count": tag_count,
            "min_count_sql": min_count is not None and ("HAVING COUNT(%s.object_id) >= %%s" % tagged_item_table) or "",
        }

        params = [tag.pk for tag in tags] * 2
        if min_count is not None:
            params.append(min_count)

        cursor = connection.cursor()
        cursor.execute(query, params)
        related = []
        for row in cursor.fetchall():
            tag = self.model.objects.get(pk=row[0])
            if counts is True:
                tag.count = row[1]
            related.append(tag)
        related.sort()
        return related
Пример #27
0
    def related_for_model(self, tags, model, counts=False, min_count=None):
        """
        Obtain a list of tags related to a given list of tags - that
        is, other tags used by items which have all the given tags.

        If ``counts`` is True, a ``count`` attribute will be added to
        each tag, indicating the number of items which have it in
        addition to the given list of tags.

        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``.
        """
        from tagging.models import TaggedItem
        if min_count is not None: counts = True
        tags = get_tag_list(tags)
        tag_count = len(tags)
        tagged_item_table = qn(TaggedItem._meta.db_table)
        query = """
        SELECT %(tag)s.id, %(tag)s.name%(count_sql)s
        FROM %(tagged_item)s INNER JOIN %(tag)s ON %(tagged_item)s.tag_id = %(tag)s.id
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.object_id IN
          (
              SELECT %(tagged_item)s.object_id
              FROM %(tagged_item)s, %(tag)s
              WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
                AND %(tag)s.id = %(tagged_item)s.tag_id
                AND %(tag)s.id IN (%(tag_id_placeholders)s)
              GROUP BY %(tagged_item)s.object_id
              HAVING COUNT(%(tagged_item)s.object_id) = %(tag_count)s
          )
          AND %(tag)s.id NOT IN (%(tag_id_placeholders)s)
        GROUP BY %(tag)s.id, %(tag)s.name
        %(min_count_sql)s
        ORDER BY %(tag)s.name ASC""" % {
            'tag': qn(self.model._meta.db_table),
            'count_sql': counts and ', COUNT(%s.object_id)' % tagged_item_table or '',
            'tagged_item': tagged_item_table,
            'content_type_id': ContentType.objects.get_for_model(model).pk,
            'tag_id_placeholders': ','.join(['%s'] * tag_count),
            'tag_count': tag_count,
            'min_count_sql': min_count is not None and ('HAVING COUNT(%s.object_id) >= %%s' % tagged_item_table) or '',
        }

        params = [tag.pk for tag in tags] * 2
        if min_count is not None:
            params.append(min_count)

        cursor = connection.cursor()
        cursor.execute(query, params)
        related = []
        for row in cursor.fetchall():
            tag = self.model(id=row[0], name=row[1])
            if counts is True:
                tag.count = row[2]
            related.append(tag)
        return related
Пример #28
0
def delete_story_tags(sender, instance, **kwargs):
    ctype = ContentType.objects.get_for_model(instance)
    tags = get_tag_list(instance.tags)
    TaggedItem._default_manager.filter(content_type__pk=ctype.pk,
                                       object_id=instance.pk,
                                       tag__in=tags).delete()
    for tag in tags:
        if not tag.items.count():
            tag.delete()
Пример #29
0
def delete_story_tags(sender, instance, **kwargs):
    ctype = ContentType.objects.get_for_model(instance)
    tags = get_tag_list(instance.tags)
    TaggedItem._default_manager.filter(content_type__pk=ctype.pk,
                                       object_id=instance.pk,
                                       tag__in=tags).delete()
    for tag in tags:
        if not tag.items.count():
            tag.delete()
Пример #30
0
 def render(self, request, place, content, context, *args, **kwargs):
     if content and content.tags:
         content_tags = [i.name for i in get_tag_list(content.tags)]
         taglist = ITag.objects.filter(name__in=content_tags)
         return self.render_block(
             request,
             template_name='itags/blocks/content_tags.html',
             context={'taglist': taglist})
     return ''
Пример #31
0
 def get_related(self, tags, relation_types=['~']):
     """
     Takes a list of tags and returns tags that are related to all of them
     """ 
     tags = get_tag_list(tags)
     result_tags = Tag.objects.all().distinct()
     for tag in tags:
         result_tags = result_tags & tag.get_related(relation_types=relation_types)
     return result_tags
Пример #32
0
 def clean(self, value):
     if self.required and not value:
         raise ValidationError(self.error_messages['required'])
     elif not self.required and not value:
         return []
     try:
         return get_tag_list(value)
     except ValueError:
         raise ValidationError(self.error_messages['list'])
Пример #33
0
def combine_tags(request, template_name="tags/tagcloud.html", form_class=CombineTagsForm):
    
    def get_not_deleted_tribe_wikies():
        deleted_tribes = Tribe.objects.filter(deleted=True)
        ctype_tribe = ContentType.objects.get(name="tribe")
        return  WikiArticle.objects.all().filter(content_type=ctype_tribe).exclude(object_id__in=deleted_tribes)
    
    # @todo: cache det her 
    query = (
       ("phototags", Image.objects.all()),
       ("bookmarktags", BookmarkInstance.objects.all()),
       ("tribe_tags", Tribe.objects.all().filter(deleted=False)),
       ("tribe_topic_tags", TribeTopic.objects.all().filter(tribe__deleted=False)),
       ("wiki_article_tags", get_not_deleted_tribe_wikies()),
       ("document_tags", Document.objects.all().filter(tribe__deleted=False)),
       )
    
    tags = []

    if request.method == "POST":
        
        combine_form = form_class(request.POST)
        
        if combine_form.is_valid():
            return_dict = {}
            tags = combine_form.cleaned_data['tags']
            
            if request.POST["bool"] == "AND":
                if len(get_tag_list(tags)) == len(tags):
                    
                    # If all of the userinput tags are valid, then there's a 
                    # point in searching for objects that contain them all.
                    # Otherwise only the excisting tags would be used when 
                    # comparing.
                     
                    for name, thing in query:
                        return_dict[name] = TaggedItem.objects.get_intersection_by_model(thing, tags)
            elif request.POST["bool"] == "OR": # If either of the tags..
                for name, thing in query:
                    return_dict[name] = TaggedItem.objects.get_union_by_model(thing, tags)
            
            return_dict.update({
                "form": combine_form,
                "tags": tags,
                'tag_cloud' : tagcloud(),
            })
            
            return render_to_response(template_name, return_dict, context_instance=RequestContext(request))            
    else:
        combine_form = form_class()

    return render_to_response(template_name, {
        "form": combine_form,
        "tags": tags,
        'tag_cloud' : tagcloud(),
    }, context_instance=RequestContext(request))
Пример #34
0
 def testNormalisedTagListInput(self):
     cheese = Tag.objects.create(name='cheese')
     toast = Tag.objects.create(name='toast')
     self.assertListsEqual([cheese], get_tag_list(cheese))
     self.assertListsEqual([cheese, toast], get_tag_list('cheese toast'))
     self.assertListsEqual([cheese, toast], get_tag_list('cheese,toast'))
     self.assertListsEqual([], get_tag_list([]))
     self.assertListsEqual([cheese, toast],
                           get_tag_list(['cheese', 'toast']))
     self.assertListsEqual([cheese, toast],
                           get_tag_list([cheese.id, toast.id]))
     self.assertListsEqual([cheese, toast],
                           get_tag_list(['cheese', 'toast', 'ŠĐĆŽćžšđ']))
     self.assertListsEqual([cheese, toast], get_tag_list([cheese, toast]))
     self.assertEqual((cheese, toast), get_tag_list((cheese, toast)))
     self.assertListsEqual(
         [cheese, toast],
         get_tag_list(Tag.objects.filter(name__in=['cheese', 'toast'])))
     self.assertRaises(ValueError, get_tag_list, ['cheese', toast])
     self.assertRaises(ValueError, get_tag_list, 29)
Пример #35
0
    def get_intersection_by_model(self, queryset_or_model, tags, include_synonyms=True):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with *all* of the given list of tags.
        """
        tags = get_tag_list(tags)
        tag_count = len(tags)

        if not tag_count:
            return model._default_manager.none()
        
        # replace the tags with their preferred synonyms if they exist
        temp_tags = []
        for tag in tags:
            try:
                rt = RelatedTag.objects.get(tag=tag, relation_type='=>')
            except RelatedTag.DoesNotExist:
                temp_tags.append(tag)
            else:
                temp_tags.append(rt.related_tag)
        
        # make sure the tags are unique
        tags = list(set(temp_tags))

        queryset, model = get_queryset_and_model(queryset_or_model)

        model_table = qn(model._meta.db_table)
        # This query selects the ids of all objects which have all the
        # given tags.
        query = """
        SELECT %(model_pk)s
        FROM %(model)s, %(tagged_item)s
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
          AND %(model_pk)s = %(tagged_item)s.object_id
        GROUP BY %(model_pk)s
        HAVING COUNT(%(model_pk)s) = %(tag_count)s""" % {
            'model_pk': '%s.%s' % (model_table, qn(model._meta.pk.column)),
            'model': model_table,
            'tagged_item': qn(self.model._meta.db_table),
            'content_type_id': ContentType.objects.get_for_model(model).pk,
            'tag_id_placeholders': ','.join(['%s'] * tag_count),
            'tag_count': tag_count,
        }
        print query, ','.join(['%s'] * tag_count), [tag.pk for tag in tags]

        cursor = connection.cursor()
        cursor.execute(query, [tag.pk for tag in tags])
        object_ids = [row[0] for row in cursor.fetchall()]
        if len(object_ids) > 0:
            return queryset.filter(pk__in=object_ids)
        else:
            return model._default_manager.none()
Пример #36
0
    def testForcingTagsToLowercase(self):
        settings.FORCE_LOWERCASE_TAGS = True

        dead = Parrot.objects.create(state='dead')
        Tag.objects.update_tags(dead, 'foO bAr Ter')
        self.assertListsEqual(get_tag_list('bar foo ter'), Tag.objects.get_for_object(dead))

        Tag.objects.update_tags(dead, 'foO bAr baZ')
        self.assertListsEqual(get_tag_list('bar baz foo'), Tag.objects.get_for_object(dead))

        Tag.objects.add_tag(dead, 'FOO')
        self.assertListsEqual(get_tag_list('bar baz foo'), Tag.objects.get_for_object(dead))

        Tag.objects.add_tag(dead, 'Zip')
        self.assertListsEqual(get_tag_list('bar baz foo zip'), Tag.objects.get_for_object(dead))

        Tag.objects.update_tags(dead, None)
        f1 = FormTest.objects.create(tags=u'test3 test2 test1')
        f1.tags = u'TEST5'
        f1.save()
        self.assertListsEqual(get_tag_list('test5'), Tag.objects.get_for_object(f1))
        self.assertEqual(u'test5', f1.tags)
Пример #37
0
def delete_story_tags(sender, instance, **kwargs):
    try:
        ctype = ContentType.objects.get_for_model(instance)
        tags = get_tag_list(instance.tags)
        TaggedItem._default_manager.filter(content_type__pk=ctype.pk,
                                           object_id=instance.pk,
                                           tag__in=tags).delete()
        for tag in tags:
            if not tag.items.count():
                tag.delete()
    except Exception, e:
        # let 'django.request' logger handle the exception
        raise e
Пример #38
0
    def get_intersection_by_model(self, Model, tags):
        """
        Create a queryset matching instances of the given Model
        associated with all the given list of Tags.

        FIXME The query currently used to grab the ids of objects
              which have all the tags should be all that we need run,
              using a non-explicit join for the QuerySet returned, as
              in get_by_model, but there's currently no way to get the
              required GROUP BY and HAVING clauses into Django's ORM.

              Once the ORM is capable of this, we should have a
              solution which requires only a single query and won't
              have the problem where the number of ids in the IN
              clause in the QuerySet could exceed the length allowed,
              as could currently happen.
        """
        tags = get_tag_list(tags)
        tag_count = len(tags)
        model_table = backend.quote_name(Model._meta.db_table)
        # This query selects the ids of all objects which have all the
        # given tags.
        query = """
        SELECT %(model_pk)s
        FROM %(model)s, %(tagged_item)s
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
          AND %(model_pk)s = %(tagged_item)s.object_id
        GROUP BY %(model_pk)s
        HAVING COUNT(%(model_pk)s) = %(tag_count)s""" % {
            'model_pk':
            '%s.%s' % (model_table, backend.quote_name(Model._meta.pk.column)),
            'model':
            model_table,
            'tagged_item':
            backend.quote_name(self.model._meta.db_table),
            'content_type_id':
            ContentType.objects.get_for_model(Model).id,
            'tag_id_placeholders':
            ','.join(['%s'] * tag_count),
            'tag_count':
            tag_count,
        }

        cursor = connection.cursor()
        cursor.execute(query, [tag.id for tag in tags])
        object_ids = [row[0] for row in cursor.fetchall()]
        if len(object_ids) > 0:
            return Model._default_manager.filter(pk__in=object_ids)
        else:
            return Model._default_manager.none()
Пример #39
0
    def get_intersection_by_model(self,
                                  queryset_or_model,
                                  tags,
                                  wildcard=None,
                                  default_namespace=None):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with *all* of the given list of tags.

        The ``wildcard`` and the ``default_namespace`` parameters are
        allowed. For more details see the ``get_tag_list`` function.
        """
        tags = get_tag_list(tags,
                            wildcard=wildcard,
                            default_namespace=default_namespace)
        tag_count = len(tags)
        queryset, model = get_queryset_and_model(queryset_or_model)

        if not tag_count:
            return model._default_manager.none()

        model_table = qn(model._meta.db_table)
        # This query selects the ids of all objects which have all the
        # given tags.
        query = """
        SELECT %(model_pk)s
        FROM %(model)s, %(tagged_item)s
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
          AND %(model_pk)s = %(tagged_item)s.object_id
        GROUP BY %(model_pk)s
        HAVING COUNT(%(model_pk)s) = %(tag_count)s""" % {
            'model_pk': '%s.%s' % (model_table, qn(model._meta.pk.column)),
            'model': model_table,
            'tagged_item': qn(self.model._meta.db_table),
            'content_type_id': ContentType.objects.get_for_model(model).pk,
            'tag_id_placeholders': ','.join(['%s'] * tag_count),
            'tag_count': tag_count,
        }

        cursor = connection.cursor()
        cursor.execute(query, [tag.pk for tag in tags])
        object_ids = [row[0] for row in cursor.fetchall()]
        if len(object_ids) > 0:
            return queryset.filter(pk__in=object_ids)
        else:
            return model._default_manager.none()
Пример #40
0
def tagged_object_list(request,
                       queryset=None,
                       tags=None,
                       related_tags=False,
                       related_tag_counts=True,
                       union=True,
                       **kwargs):
    """
    A thin wrapper around
    ``django.views.generic.list_detail.object_list`` which creates a
    ``QuerySet`` containing instances of the given queryset or model
    tagged with the given tag.

    In addition to the context variables set up by ``object_list``, a
    ``tag`` context variable will contain the ``Tag`` instance for the
    tag.

    If ``related_tags`` is ``True``, a ``related_tags`` context variable
    will contain tags related to the given tag for the given model.
    Additionally, if ``related_tag_counts`` is ``True``, each related
    tag will have a ``count`` attribute indicating the number of items
    which have it in addition to the given tag.

    If ``union`` is ``True``, will return list of objects, which are marked
    by one of mentioned tags. In other case will return list of object, which
    are marked by all of mentioned tags.
    """
    tag_instances = get_tag_list(tags)
    if not tag_instances:
        raise Http404
    if union:
        qs_func = TaggedItem.objects.get_union_by_model
    else:
        qs_func = TaggedItem.objects.get_intersection_by_model
    if not kwargs.has_key('extra_context'):
        kwargs['extra_context'] = {}
    kwargs['extra_context']['union'] = union
    if tag_instances:
        queryset = qs_func(queryset, tag_instances)
        kwargs['extra_context']['tags'] = tag_instances
        if related_tags:
            kwargs['extra_context']['related_tags'] = \
                Tag.objects.related_for_model(tag_instances, queryset,
                                              counts=related_tag_counts)
    else:
        queryset = get_queryset_and_model(queryset)[0]
    return object_list(request, queryset, **kwargs)
Пример #41
0
	def get_intersection_by_model(self, model, tags):
		"""
		Create a queryset matching instances of the given Model
		associated with all the given list of Tags.
		
		FIXME The query currently used to grab the ids of objects
		      which have all the tags should be all that we need run,
		      using a non-explicit join for the QuerySet returned, as
		      in get_by_model, but there's currently no way to get the
		      required GROUP BY and HAVING clauses into Django's ORM.
		
		      Once the ORM is capable of this, we should have a
		      solution which requires only a single query and won't
		      have the problem where the number of ids in the IN
		      clause in the QuerySet could exceed the length allowed,
		      as could currently happen.
		"""
		tags = get_tag_list(tags)
		tag_count = len(tags)
		model_table = qn(model._meta.db_table)
		# This query selects the ids of all objects which have all the
		# given tags.
		query = """
		SELECT %(model_pk)s
		FROM %(model)s, %(tagged_item)s
		WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
			AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
			AND %(model_pk)s = %(tagged_item)s.object_id
		GROUP BY %(model_pk)s
		HAVING COUNT(%(model_pk)s) = %(tag_count)s""" % {
			'model_pk': '%s.%s' % (model_table, qn(model._meta.pk.column)),
			'model': model_table,
			'tagged_item': qn(self.model._meta.db_table),
			'content_type_id': ContentType.objects.get_for_model(model).pk,
			'tag_id_placeholders': ','.join(['%s'] * tag_count),
			'tag_count': tag_count,
		}
		
		cursor = connection.cursor()
		cursor.execute(query, [tag.pk for tag in tags])
		object_ids = [row[0] for row in cursor.fetchall()]
		if len(object_ids) > 0:
			return model._default_manager.filter(pk__in=object_ids)
		else:
			return model._default_manager.none()
Пример #42
0
 def relate_all(self, tags):
     '''
     Relates a list of tags with each other (for '~' relations only)
     '''
     tags = get_tag_list(tags)
     for tag in tags:
         tag = get_tag(tag)
         if tag and tag.is_valid:
                 for related_tag in tags:
                     related_tag = get_tag(related_tag)
                     if related_tag and related_tag.is_valid:
                             if tag != related_tag:
                                 rel, c = RelatedTag.objects.get_or_create(tag=tag, related_tag=related_tag,
                                                                           defaults={'relation_type': '~',
                                                                                     'count': 1})
                                 if not c:
                                     rel.count += 1
                                     rel.save()
Пример #43
0
    def get_intersection(self, user_list, tag_list):
        tags = get_tag_list(tag_list)
        tags_id = [int(tag.pk) for tag in tags]
        tags_id.append(0)
        tags_id.append(0)
        user_list.append(0)
        user_list.append(0)
        query = """
        SELECT DISTINCT flow_flow.id
        FROM flow_flow INNER JOIN tagging_taggeditem ON flow_flow.id = tagging_taggeditem.object_id
        WHERE post = 1 AND (user_id IN %(user_list)s OR tag_id IN %(tag_list)s)""" % {
            'user_list': tuple(user_list),
            'tag_list': tuple(tags_id)
        }

        cursor = connection.cursor()
        cursor.execute(query)
        object_ids = [row[0] for row in cursor.fetchall()]
        return self.model.objects.select_related().filter(pk__in = object_ids)
Пример #44
0
    def get_intersection_by_model(self, queryset_or_model, tags,
                                  wildcard=None, default_namespace=None):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with *all* of the given list of tags.

        The ``wildcard`` and the ``default_namespace`` parameters are
        allowed. For more details see the ``get_tag_list`` function.
        """
        tags = get_tag_list(tags,
            wildcard=wildcard, default_namespace=default_namespace)
        tag_count = len(tags)
        queryset, model = get_queryset_and_model(queryset_or_model)

        if not tag_count:
            return model._default_manager.none()

        model_table = qn(model._meta.db_table)
        # This query selects the ids of all objects which have all the
        # given tags.
        query = """
        SELECT %(model_pk)s
        FROM %(model)s, %(tagged_item)s
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
          AND %(model_pk)s = %(tagged_item)s.object_id
        GROUP BY %(model_pk)s
        HAVING COUNT(%(model_pk)s) = %(tag_count)s""" % {
            'model_pk': '%s.%s' % (model_table, qn(model._meta.pk.column)),
            'model': model_table,
            'tagged_item': qn(self.model._meta.db_table),
            'content_type_id': ContentType.objects.get_for_model(model).pk,
            'tag_id_placeholders': ','.join(['%s'] * tag_count),
            'tag_count': tag_count,
        }

        cursor = connection.cursor()
        cursor.execute(query, [tag.pk for tag in tags])
        object_ids = [row[0] for row in cursor.fetchall()]
        if len(object_ids) > 0:
            return queryset.filter(pk__in=object_ids)
        else:
            return model._default_manager.none()
Пример #45
0
def category(request, slug):

    category = Category.objects.get(slug=slug)

    # get posts: first published posts, then filter to findatcat tag,
    # then any matching category tag
    qs = Post.objects.published().select_related()
    qs = TaggedItem.objects.get_by_model(qs, get_tag('Finance Data Catalog'))
    posts = TaggedItem.objects.get_union_by_model(
        qs, get_tag_list(category.tag_list()))

    context = {
        'posts': posts,
        'links': category.links.all(),
        'current_category': category,
        'categories': Category.objects.all(),
    }

    return render_to_response('findatcat/category.html', context)
Пример #46
0
def tagged_object_list(request, queryset=None, tags=None, related_tags=False,
                       related_tag_counts=True, union=True, **kwargs):
    """
    A thin wrapper around
    ``django.views.generic.list_detail.object_list`` which creates a
    ``QuerySet`` containing instances of the given queryset or model
    tagged with the given tag.

    In addition to the context variables set up by ``object_list``, a
    ``tag`` context variable will contain the ``Tag`` instance for the
    tag.

    If ``related_tags`` is ``True``, a ``related_tags`` context variable
    will contain tags related to the given tag for the given model.
    Additionally, if ``related_tag_counts`` is ``True``, each related
    tag will have a ``count`` attribute indicating the number of items
    which have it in addition to the given tag.

    If ``union`` is ``True``, will return list of objects, which are marked
    by one of mentioned tags. In other case will return list of object, which
    are marked by all of mentioned tags.
    """
    tag_instances = get_tag_list(tags)
    if not tag_instances:
        raise Http404
    if union:
        qs_func = TaggedItem.objects.get_union_by_model
    else:
        qs_func = TaggedItem.objects.get_intersection_by_model
    if not kwargs.has_key('extra_context'):
        kwargs['extra_context'] = {}
    kwargs['extra_context']['union'] = union
    if tag_instances:
        queryset = qs_func(queryset, tag_instances)
        kwargs['extra_context']['tags'] = tag_instances
        if related_tags:
            kwargs['extra_context']['related_tags'] = \
                Tag.objects.related_for_model(tag_instances, queryset,
                                              counts=related_tag_counts)
    else:
        queryset = get_queryset_and_model(queryset)[0]
    return object_list(request, queryset, **kwargs)
Пример #47
0
 def get_by_model(self, queryset_or_model, tags, include_synonyms=True):
     # TODO: we may remove include synonyms as the preferred synonym is forced when tagging
     """
     Create a ``QuerySet`` containing instances of the specified
     model associated with a given tag or list of tags.
     """
     tags = get_tag_list(tags)
     tag_count = len(tags)
     if tag_count == 0:
         # No existing tags were given
         queryset, model = get_queryset_and_model(queryset_or_model)
         return model._default_manager.none()
     elif tag_count == 1:
         # Optimization for single tag - fall through to the simpler
         # query below.
         tag = tags[0]
         if include_synonyms:
             related_tags = tag.get_related(relation_types=['=', '=>', '<='])
             if related_tags.count() > 0:
                 # we have synonyms; 1 tag & n synonyms; return the union
                 return self.get_union_by_model(queryset_or_model, [tag] + list(related_tags))
         # No synonyms; go on with the usual way
         queryset, model = get_queryset_and_model(queryset_or_model)
         content_type = ContentType.objects.get_for_model(model)
         db_table = self.model._meta.db_table
         tagged_item_table = qn(db_table)
         return queryset.extra(
             tables=[db_table],
             where=[
                 '%s.content_type_id = %%s' % tagged_item_table,
                 '%s.tag_id = %%s' % tagged_item_table,
                 '%s.%s = %s.object_id' % (qn(model._meta.db_table),
                                           qn(model._meta.pk.column),
                                           tagged_item_table)
             ],
             params=[content_type.pk, tag.pk],
         )
     else:
         # we have multiple tags
         return self.get_intersection_by_model(queryset_or_model, tags, 
                                               include_synonyms=include_synonyms)
Пример #48
0
    def get_intersection_by_model(self, queryset_or_model, tags):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with *all* of the given list of tags.
        """
        tags = get_tag_list(tags)
        tag_count = len(tags)
        queryset, model = get_queryset_and_model(queryset_or_model)

        if not tag_count:
            return model._default_manager.none()

        model_table = qn(model._meta.db_table)
        # This query selects the ids of all objects which have all the
        # given tags.
        query = """
        SELECT %(model_pk)s
        FROM %(model)s, %(tagged_item)s
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
          AND %(model_pk)s = %(tagged_item)s.object_id
        GROUP BY %(model_pk)s
        HAVING COUNT(%(model_pk)s) = %(tag_count)s""" % {
            "model_pk": "%s.%s" % (model_table, qn(model._meta.pk.column)),
            "model": model_table,
            "tagged_item": qn(self.model._meta.db_table),
            "content_type_id": ContentType.objects.get_for_model(model).pk,
            "tag_id_placeholders": ",".join(["%s"] * tag_count),
            "tag_count": tag_count,
        }

        cursor = connection.cursor()
        cursor.execute(query, [tag.pk for tag in tags])
        object_ids = [row[0] for row in cursor.fetchall()]
        if len(object_ids) > 0:
            return queryset.filter(pk__in=object_ids)
        else:
            return model._default_manager.none()
Пример #49
0
    def get_intersection_by_model(self, queryset_or_model, tags):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with *all* of the given list of tags.
        """
        tags = get_tag_list(tags)
        tag_count = len(tags)
        queryset, model = get_queryset_and_model(queryset_or_model)

        if not tag_count:
            return model._default_manager.none()

        model_table = qn(model._meta.db_table)
        # This query selects the ids of all objects which have all the
        # given tags.
        query = """
        SELECT %(model_pk)s
        FROM %(model)s, %(tagged_item)s
        WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
          AND %(tagged_item)s.tag_id IN (%(tag_id_placeholders)s)
          AND %(model_pk)s = %(tagged_item)s.object_id
        GROUP BY %(model_pk)s
        HAVING COUNT(%(model_pk)s) = %(tag_count)s""" % {
            "model_pk": "%s.%s" % (model_table, qn(model._meta.pk.column)),
            "model": model_table,
            "tagged_item": qn(self.model._meta.db_table),
            "content_type_id": ContentType.objects.get_for_model(model).pk,
            "tag_id_placeholders": ",".join(["%s"] * tag_count),
            "tag_count": tag_count,
        }

        cursor = connection.cursor()
        cursor.execute(query, [tag.pk for tag in tags])
        object_ids = [row[0] for row in cursor.fetchall()]
        if len(object_ids) > 0:
            return queryset.filter(pk__in=object_ids)
        else:
            return model._default_manager.none()
Пример #50
0
 def get_by_model(self, Model, tags):
     """
     Create a queryset matching instances of the given Model
     associated with a given Tag or list of Tags.
     """
     tags = get_tag_list(tags)
     if len(tags) == 1:
         tag = tags[0]  # Optimisation for single tag
     else:
         return self.get_intersection_by_model(Model, tags)
     ctype = ContentType.objects.get_for_model(Model)
     rel_table = backend.quote_name(self.model._meta.db_table)
     return Model._default_manager.extra(
         tables=[self.model._meta.db_table],  # Use a non-explicit join
         where=[
             '%s.content_type_id = %%s' % rel_table,
             '%s.tag_id = %%s' % rel_table,
             '%s.%s = %s.object_id' %
             (backend.quote_name(Model._meta.db_table),
              backend.quote_name(Model._meta.pk.column), rel_table)
         ],
         params=[ctype.id, tag.id],
     )
Пример #51
0
    def get_intersection_by_model(self, queryset_or_model, tags):
        """
        Create a ``QuerySet`` containing instances of the specified
        model associated with *all* of the given list of tags.
        """
        tags = get_tag_list(tags)
        tag_count = len(tags)
        queryset, model = get_queryset_and_model(queryset_or_model)

        if not tag_count:
            return model._default_manager.none()

        model_table = qn(model._meta.db_table)
        tagged_item_table = qn(self.model._meta.db_table)
        # This query selects the ids of all objects which have all the
        # given tags.
        joins, params = self.get_tagged_item_joins(tags, tagged_item_table, model)
        
        query = '''
        SELECT %(model_pk)s
        FROM %(model)s
        %(joins)s
        GROUP BY %(model_pk)s
        ''' % {
            'model': model_table,
            'model_pk': '%s.%s' % (model_table, qn(model._meta.pk.column)),
            'joins': joins,
        }

        cursor = connection.cursor()
        cursor.execute(query, params)
        object_ids = [row[0] for row in cursor.fetchall()]
        if len(object_ids) > 0:
            return queryset.filter(pk__in=object_ids)
        else:
            return model._default_manager.none()
Пример #52
0
 def render(self, context, instance, placeholder):
     """
         Render the latest entries
     """
     qs = Entry.published.all()
     
     if instance.current_language_only:
         language = get_language_from_request(context["request"])
         kw = get_translation_filter_language(Entry, language)
         qs = qs.filter(**kw)
         
     if instance.tagged:
         tags = get_tag_list(instance.tagged)
         qs  = TaggedItem.objects.get_by_model(qs , tags)
         
     latest = qs[:instance.limit]
     
     context.update({
         'instance': instance,
         'latest': latest,
         'object_list': latest,
         'placeholder': placeholder
     })
     return context
Пример #53
0
 def test_comma_delimeted_string_as_input(self):
     ret = get_tag_list('cheese,toast')
     self.assertEquals(len(ret), 2)
     self.failUnless(self.cheese in ret)
     self.failUnless(self.toast in ret)
Пример #54
0
 def test_single_tag_object_as_input(self):
     self.assertEquals(get_tag_list(self.cheese), [self.cheese])
Пример #55
0
 def test_with_invalid_input(self):
     try:
         get_tag_list(29)
     except ValueError, ve:
         self.assertEquals(str(ve), 'The tag input given was invalid.')
Пример #56
0
 def test_with_tag_filter(self):
     ret = get_tag_list(Tag.objects.filter(name__in=['cheese', 'toast']))
     self.assertEquals(len(ret), 2)
     self.failUnless(self.cheese in ret)
     self.failUnless(self.toast in ret)
Пример #57
0
 def test_tuple_of_instances(self):
     ret = get_tag_list((self.cheese, self.toast))
     self.assertEquals(len(ret), 2)
     self.failUnless(self.cheese in ret)
     self.failUnless(self.toast in ret)