##// END OF EJS Templates
Fixed issue with deferring a field no more exists
neko259 -
r1079:efaf1251 default
parent child Browse files
Show More
@@ -1,200 +1,200 b''
1 1 import logging
2 2
3 3 from django.db.models import Count, Sum
4 4 from django.utils import timezone
5 5 from django.db import models
6 6
7 7 from boards import settings
8 8 import boards
9 9 from boards.utils import cached_result
10 10 from boards.models.post import Post
11 11
12 12
13 13 __author__ = 'neko259'
14 14
15 15
16 16 logger = logging.getLogger(__name__)
17 17
18 18
19 19 class ThreadManager(models.Manager):
20 20 def process_oldest_threads(self):
21 21 """
22 22 Preserves maximum thread count. If there are too many threads,
23 23 archive or delete the old ones.
24 24 """
25 25
26 26 threads = Thread.objects.filter(archived=False).order_by('-bump_time')
27 27 thread_count = threads.count()
28 28
29 29 if thread_count > settings.MAX_THREAD_COUNT:
30 30 num_threads_to_delete = thread_count - settings.MAX_THREAD_COUNT
31 31 old_threads = threads[thread_count - num_threads_to_delete:]
32 32
33 33 for thread in old_threads:
34 34 if settings.ARCHIVE_THREADS:
35 35 self._archive_thread(thread)
36 36 else:
37 37 thread.delete()
38 38
39 39 logger.info('Processed %d old threads' % num_threads_to_delete)
40 40
41 41 def _archive_thread(self, thread):
42 42 thread.archived = True
43 43 thread.bumpable = False
44 44 thread.last_edit_time = timezone.now()
45 45 thread.update_posts_time()
46 46 thread.save(update_fields=['archived', 'last_edit_time', 'bumpable'])
47 47
48 48
49 49 class Thread(models.Model):
50 50 objects = ThreadManager()
51 51
52 52 class Meta:
53 53 app_label = 'boards'
54 54
55 55 tags = models.ManyToManyField('Tag')
56 56 bump_time = models.DateTimeField(db_index=True)
57 57 last_edit_time = models.DateTimeField()
58 58 archived = models.BooleanField(default=False)
59 59 bumpable = models.BooleanField(default=True)
60 60 max_posts = models.IntegerField(default=settings.MAX_POSTS_PER_THREAD)
61 61
62 62 def get_tags(self):
63 63 """
64 64 Gets a sorted tag list.
65 65 """
66 66
67 67 return self.tags.order_by('name')
68 68
69 69 def bump(self):
70 70 """
71 71 Bumps (moves to up) thread if possible.
72 72 """
73 73
74 74 if self.can_bump():
75 75 self.bump_time = self.last_edit_time
76 76
77 77 self.update_bump_status()
78 78
79 79 logger.info('Bumped thread %d' % self.id)
80 80
81 81 def has_post_limit(self):
82 82 return self.max_posts > 0
83 83
84 84 def update_bump_status(self):
85 85 if self.has_post_limit() and self.get_reply_count() >= self.max_posts:
86 86 self.bumpable = False
87 87 self.update_posts_time()
88 88
89 89 def get_reply_count(self):
90 90 return self.get_replies().count()
91 91
92 92 def get_images_count(self):
93 93 return self.get_replies().annotate(images_count=Count(
94 94 'images')).aggregate(Sum('images_count'))['images_count__sum']
95 95
96 96 def can_bump(self):
97 97 """
98 98 Checks if the thread can be bumped by replying to it.
99 99 """
100 100
101 101 return self.bumpable and not self.archived
102 102
103 103 def get_last_replies(self):
104 104 """
105 105 Gets several last replies, not including opening post
106 106 """
107 107
108 108 if settings.LAST_REPLIES_COUNT > 0:
109 109 reply_count = self.get_reply_count()
110 110
111 111 if reply_count > 0:
112 112 reply_count_to_show = min(settings.LAST_REPLIES_COUNT,
113 113 reply_count - 1)
114 114 replies = self.get_replies()
115 115 last_replies = replies[reply_count - reply_count_to_show:]
116 116
117 117 return last_replies
118 118
119 119 def get_skipped_replies_count(self):
120 120 """
121 121 Gets number of posts between opening post and last replies.
122 122 """
123 123 reply_count = self.get_reply_count()
124 124 last_replies_count = min(settings.LAST_REPLIES_COUNT,
125 125 reply_count - 1)
126 126 return reply_count - last_replies_count - 1
127 127
128 128 def get_replies(self, view_fields_only=False):
129 129 """
130 130 Gets sorted thread posts
131 131 """
132 132
133 133 query = Post.objects.filter(threads__in=[self])
134 134 query = query.order_by('pub_time').prefetch_related('images', 'thread', 'threads')
135 135 if view_fields_only:
136 query = query.defer('poster_user_agent')
136 query = query.defer('poster_ip')
137 137 return query.all()
138 138
139 139 def get_replies_with_images(self, view_fields_only=False):
140 140 """
141 141 Gets replies that have at least one image attached
142 142 """
143 143
144 144 return self.get_replies(view_fields_only).annotate(images_count=Count(
145 145 'images')).filter(images_count__gt=0)
146 146
147 147 def add_tag(self, tag):
148 148 """
149 149 Connects thread to a tag and tag to a thread
150 150 """
151 151
152 152 self.tags.add(tag)
153 153
154 154 def get_opening_post(self, only_id=False):
155 155 """
156 156 Gets the first post of the thread
157 157 """
158 158
159 159 query = self.get_replies().order_by('pub_time')
160 160 if only_id:
161 161 query = query.only('id')
162 162 opening_post = query.first()
163 163
164 164 return opening_post
165 165
166 166 @cached_result
167 167 def get_opening_post_id(self):
168 168 """
169 169 Gets ID of the first thread post.
170 170 """
171 171
172 172 return self.get_opening_post(only_id=True).id
173 173
174 174 def get_pub_time(self):
175 175 """
176 176 Gets opening post's pub time because thread does not have its own one.
177 177 """
178 178
179 179 return self.get_opening_post().pub_time
180 180
181 181 def delete(self, using=None):
182 182 """
183 183 Deletes thread with all replies.
184 184 """
185 185
186 186 for reply in self.get_replies().all():
187 187 reply.delete()
188 188
189 189 super(Thread, self).delete(using)
190 190
191 191 def __str__(self):
192 192 return 'T#{}/{}'.format(self.id, self.get_opening_post_id())
193 193
194 194 def get_tag_url_list(self):
195 195 return boards.models.Tag.objects.get_tag_url_list(self.get_tags())
196 196
197 197 def update_posts_time(self):
198 198 self.post_set.update(last_edit_time=self.last_edit_time)
199 199 for post in self.post_set.all():
200 200 post.threads.update(last_edit_time=self.last_edit_time)
General Comments 0
You need to be logged in to leave comments. Login now