3 from django.utils.translation import ugettext as _
5 question_view = django.dispatch.Signal(providing_args=['instance', 'user'])
8 accepted_answer = models.OneToOneField('Answer', null=True, related_name="question_accepting")
9 closed = models.BooleanField(default=False)
10 closed_by = models.ForeignKey(User, null=True, blank=True, related_name='closed_questions')
11 closed_at = models.DateTimeField(null=True, blank=True)
12 close_reason = models.SmallIntegerField(choices=CLOSE_REASONS, null=True, blank=True)
13 subscribers = models.ManyToManyField(User, related_name='subscriptions', through='QuestionSubscription')
16 answer_count = models.PositiveIntegerField(default=0)
17 view_count = models.IntegerField(default=0)
18 favourite_count = models.IntegerField(default=0)
19 last_activity_at = models.DateTimeField(default=datetime.datetime.now)
20 last_activity_by = models.ForeignKey(User, related_name='last_active_in_questions', null=True)
22 favorited_by = models.ManyToManyField(User, through='FavoriteQuestion', related_name='favorite_questions')
24 class Meta(QandA.Meta):
25 db_table = u'question'
30 return _('[closed] ') + self.title
33 return _('[deleted] ') + self.title
38 def answer_accepted(self):
39 return self.accepted_answer is not None
41 def save(self, *args, **kwargs):
42 if not self.last_activity_by:
43 self.last_activity_by = self.author
44 super(Question, self).save(*args, **kwargs)
46 def update_last_activity(self, user):
47 self.last_activity_by = user
48 self.last_activity_at = datetime.datetime.now()
51 def activate_revision(self, user, revision):
52 super(Question, self).activate_revision(user, revision)
53 self.update_last_activity(user)
56 def get_absolute_url(self):
57 return ('question', (), {'id': self.id, 'slug': django_urlquote(slugify(self.title))})
59 def get_answer_count_by_user(self, user_id):
60 from answer import Answer
61 query_set = Answer.objects.filter(author__id=user_id)
62 return query_set.filter(question=self).count()
64 def get_question_title(self):
66 attr = CONST['closed']
68 attr = CONST['deleted']
72 return u'%s %s' % (self.title, attr)
76 def get_revision_url(self):
77 return reverse('question_revisions', args=[self.id])
79 def get_related_questions(self, count=10):
80 cache_key = '%s.related_questions:%d:%d' % (settings.APP_URL, count, self.id)
81 related_list = cache.get(cache_key)
83 if related_list is None:
84 related_list = Question.objects.values('id').filter(tags__id__in=[t.id for t in self.tags.all()]
85 ).exclude(id=self.id).exclude(deleted=True).annotate(frequency=models.Count('id')).order_by('-frequency')[:count]
86 cache.set(cache_key, related_list, 60 * 60)
88 return [Question.objects.get(id=r['id']) for r in related_list]
90 def __unicode__(self):
93 def question_viewed(instance, **kwargs):
94 instance.view_count += 1
97 question_view.connect(question_viewed)
99 class FavoriteQuestion(models.Model):
100 question = models.ForeignKey('Question')
101 user = models.ForeignKey(User, related_name='user_favorite_questions')
102 added_at = models.DateTimeField(default=datetime.datetime.now)
105 unique_together = ('question', 'user')
107 db_table = u'favorite_question'
109 def __unicode__(self):
110 return '[%s] favorited at %s' %(self.user, self.added_at)
112 def _update_question_fav_count(self, diff):
113 self.question.favourite_count = self.question.favourite_count + diff
116 def save(self, *args, **kwargs):
117 super(FavoriteQuestion, self).save(*args, **kwargs)
119 self._update_question_fav_count(1)
122 self._update_question_fav_count(-1)
123 super(FavoriteQuestion, self).delete()
125 class QuestionSubscription(models.Model):
126 user = models.ForeignKey(User)
127 question = models.ForeignKey(Question)
128 auto_subscription = models.BooleanField(default=True)
129 last_view = models.DateTimeField(default=datetime.datetime.now())
135 class QuestionRevision(NodeRevision):