]> git.openstreetmap.org Git - osqa.git/blob - forum/models/tag.py
Initial commit
[osqa.git] / forum / models / tag.py
1 from base import *\r
2 \r
3 from django.utils.translation import ugettext as _\r
4 \r
5 class TagManager(models.Manager):\r
6     UPDATE_USED_COUNTS_QUERY = (\r
7         'UPDATE tag '\r
8         'SET used_count = ('\r
9             'SELECT COUNT(*) FROM question_tags '\r
10             'INNER JOIN question ON question_id=question.id '\r
11             'WHERE tag_id = tag.id AND question.deleted=False'\r
12         ') '\r
13         'WHERE id IN (%s)')\r
14 \r
15     def get_valid_tags(self, page_size):\r
16       tags = self.all().filter(deleted=False).exclude(used_count=0).order_by("-id")[:page_size]\r
17       return tags\r
18 \r
19     def get_or_create_multiple(self, names, user):\r
20         """\r
21         Fetches a list of Tags with the given names, creating any Tags\r
22         which don't exist when necesssary.\r
23         """\r
24         tags = list(self.filter(name__in=names))\r
25         #Set all these tag visible\r
26         for tag in tags:\r
27             if tag.deleted:\r
28                 tag.deleted = False\r
29                 tag.deleted_by = None\r
30                 tag.deleted_at = None\r
31                 tag.save()\r
32 \r
33         if len(tags) < len(names):\r
34             existing_names = set(tag.name for tag in tags)\r
35             new_names = [name for name in names if name not in existing_names]\r
36             tags.extend([self.create(name=name, created_by=user)\r
37                          for name in new_names if self.filter(name=name).count() == 0 and len(name.strip()) > 0])\r
38 \r
39         return tags\r
40 \r
41     def update_use_counts(self, tags):\r
42         """Updates the given Tags with their current use counts."""\r
43         if not tags:\r
44             return\r
45         cursor = connection.cursor()\r
46         query = self.UPDATE_USED_COUNTS_QUERY % ','.join(['%s'] * len(tags))\r
47         cursor.execute(query, [tag.id for tag in tags])\r
48         transaction.commit_unless_managed()\r
49 \r
50     def get_tags_by_questions(self, questions):\r
51         question_ids = []\r
52         for question in questions:\r
53             question_ids.append(question.id)\r
54 \r
55         question_ids_str = ','.join([str(id) for id in question_ids])\r
56         related_tags = self.extra(\r
57                 tables=['tag', 'question_tags'],\r
58                 where=["tag.id = question_tags.tag_id AND question_tags.question_id IN (" + question_ids_str + ")"]\r
59         ).distinct()\r
60 \r
61         return related_tags\r
62 \r
63 class Tag(DeletableContent):\r
64     name            = models.CharField(max_length=255, unique=True)\r
65     created_by      = models.ForeignKey(User, related_name='created_tags')\r
66     # Denormalised data\r
67     used_count = models.PositiveIntegerField(default=0)\r
68 \r
69     objects = TagManager()\r
70 \r
71     class Meta(DeletableContent.Meta):\r
72         db_table = u'tag'\r
73         ordering = ('-used_count', 'name')\r
74 \r
75     def __unicode__(self):\r
76         return self.name\r
77 \r
78 class MarkedTag(models.Model):\r
79     TAG_MARK_REASONS = (('good',_('interesting')),('bad',_('ignored')))\r
80     tag = models.ForeignKey('Tag', related_name='user_selections')\r
81     user = models.ForeignKey(User, related_name='tag_selections')\r
82     reason = models.CharField(max_length=16, choices=TAG_MARK_REASONS)\r
83 \r
84     class Meta:\r
85         app_label = 'forum'