Compare View

switch
from
...
to
 
Commits (2)
forum/views/topic.py
1 # coding: utf-8 1 # coding: utf-8
2 2
3 import json, math, hashlib 3 import json, math, hashlib
4 from django.http import HttpResponse, Http404 4 from django.http import HttpResponse, Http404
5 from django.shortcuts import render_to_response, redirect, get_object_or_404 5 from django.shortcuts import render_to_response, redirect, get_object_or_404
6 from django.contrib import auth 6 from django.contrib import auth
7 from django.contrib.auth.decorators import login_required 7 from django.contrib.auth.decorators import login_required
8 from django.template import RequestContext 8 from django.template import RequestContext
9 from django.utils import timezone 9 from django.utils import timezone
10 from django.conf import settings 10 from django.conf import settings
11 from forum.models import ForumUser, Topic, Favorite, Vote, Reply, Node, Notification, Plane 11 from forum.models import ForumUser, Topic, Favorite, Vote, Reply, Node, Notification, Plane
12 from forum.forms.topic import ReplyForm, CreateForm 12 from forum.forms.topic import ReplyForm, CreateForm
13 from common import find_mentions 13 from common import find_mentions
14 14
15 15
16 def get_index(request): 16 def get_index(request):
17 user = request.user 17 user = request.user
18 if user.is_authenticated(): 18 if user.is_authenticated():
19 counter = { 19 counter = {
20 'topics': user.topic_author.all().count(), 20 'topics': user.topic_author.all().count(),
21 'replies': user.reply_author.all().count(), 21 'replies': user.reply_author.all().count(),
22 'favorites': user.fav_user.all().count() 22 'favorites': user.fav_user.all().count()
23 } 23 }
24 notifications_count = user.notify_user.filter(status=0).count() 24 notifications_count = user.notify_user.filter(status=0).count()
25 25
26 status_counter = { 26 status_counter = {
27 'users': ForumUser.objects.all().count(), 27 'users': ForumUser.objects.all().count(),
28 'nodes': Node.objects.all().count(), 28 'nodes': Node.objects.all().count(),
29 'topics': Topic.objects.all().count(), 29 'topics': Topic.objects.all().count(),
30 'replies': Reply.objects.all().count(), 30 'replies': Reply.objects.all().count(),
31 } 31 }
32 32
33 try: 33 try:
34 current_page = int(request.GET.get('p', '1')) 34 current_page = int(request.GET.get('p', '1'))
35 except ValueError: 35 except ValueError:
36 current_page = 1 36 current_page = 1
37 37
38 topics, topic_page = Topic.objects.get_all_topic(current_page=current_page) 38 topics, topic_page = Topic.objects.get_all_topic(current_page=current_page)
39 planes = Plane.objects.all().prefetch_related('node_set') 39 planes = Plane.objects.all().prefetch_related('node_set')
40 # hot_nodes = Node.objects.get_all_hot_nodes() 40 # hot_nodes = Node.objects.get_all_hot_nodes()
41 hot_nodes = Node.objects.all() 41 hot_nodes = Node.objects.all()
42 active_page = 'topic' 42 active_page = 'topic'
43 return render_to_response('topic/topics.html', locals(), 43 return render_to_response('topic/topics.html', locals(),
44 context_instance=RequestContext(request)) 44 context_instance=RequestContext(request))
45 45
46 46
47 def get_view(request, topic_id, errors=None): 47 def get_view(request, topic_id, errors=None):
48 try: 48 try:
49 topic = Topic.objects.get_topic_by_topic_id(topic_id) 49 topic = Topic.objects.get_topic_by_topic_id(topic_id)
50 except Topic.DoesNotExist: 50 except Topic.DoesNotExist:
51 raise Http404 51 raise Http404
52
52 53 user = request.user
53 user = request.user 54 if user.is_authenticated():
54 if user.is_authenticated(): 55 counter = {
55 counter = { 56 'topics': user.topic_author.all().count(),
56 'topics': user.topic_author.all().count(), 57 'replies': user.reply_author.all().count(),
57 'replies': user.reply_author.all().count(), 58 'favorites': user.fav_user.all().count()
58 'favorites': user.fav_user.all().count() 59 }
59 } 60 notifications_count = user.notify_user.filter(status=0).count()
60 notifications_count = user.notify_user.filter(status=0).count() 61 topic_favorited = Favorite.objects.filter(involved_topic=topic, owner_user=user).exists()
61 topic_favorited = Favorite.objects.filter(involved_topic=topic, owner_user=user).exists() 62
62 63 reply_num = 106
63 reply_num = 106 64 reply_count = topic.reply_count
64 reply_count = topic.reply_count 65 reply_last_page = (reply_count // reply_num + (reply_count % reply_num and 1)) or 1
65 reply_last_page = (reply_count // reply_num + (reply_count % reply_num and 1)) or 1 66 try:
66 try: 67 current_page = int(request.GET.get('p', reply_last_page))
67 current_page = int(request.GET.get('p', reply_last_page)) 68 except ValueError:
68 except ValueError: 69 current_page = reply_last_page
69 current_page = reply_last_page 70
70 71 replies, reply_page = Reply.objects.get_all_replies_by_topic_id(topic.id, current_page=current_page, num = reply_num)
71 replies, reply_page = Reply.objects.get_all_replies_by_topic_id(topic.id, current_page=current_page, num = reply_num) 72 active_page = 'topic'
72 active_page = 'topic' 73 floor = reply_num * (current_page - 1)
73 floor = reply_num * (current_page - 1) 74
74 75 topic.reply_count = reply_page.total
75 topic.reply_count = reply_page.total 76 topic.hits = (topic.hits or 0) + 1
76 topic.hits = (topic.hits or 0) + 1 77 topic.save()
77 topic.save() 78 return render_to_response('topic/view.html', locals(),
78 return render_to_response('topic/view.html', locals(), 79 context_instance=RequestContext(request))
79 context_instance=RequestContext(request)) 80
80 81
81 82 @login_required
82 @login_required 83 def post_view(request, topic_id):
83 def post_view(request, topic_id): 84 try:
84 try: 85 topic = Topic.objects.select_related('author').get(pk=topic_id)
85 topic = Topic.objects.select_related('author').get(pk=topic_id) 86 except Topic.DoesNotExist:
86 except Topic.DoesNotExist: 87 raise Http404
87 raise Http404 88 form = ReplyForm(request.POST)
88 form = ReplyForm(request.POST) 89 if not form.is_valid():
89 if not form.is_valid(): 90 return get_view(request, topic_id, errors=form.errors)
90 return get_view(request, topic_id, errors=form.errors) 91
91 92 user = request.user
92 user = request.user 93 try:
93 try: 94 last_reply = topic.reply_set.all().order_by('-created')[0]
94 last_reply = topic.reply_set.all().order_by('-created')[0] 95 except IndexError:
95 except IndexError: 96 last_reply = None
96 last_reply = None 97 if last_reply:
97 if last_reply: 98 last_replied_fingerprint = hashlib.sha1(str(topic.id) + str(last_reply.author_id) + last_reply.content).hexdigest()
98 last_replied_fingerprint = hashlib.sha1(str(topic.id) + str(last_reply.author_id) + last_reply.content).hexdigest() 99 new_replied_fingerprint = hashlib.sha1(str(topic.id) + str(user.id) + form.cleaned_data.get('content')).hexdigest()
99 new_replied_fingerprint = hashlib.sha1(str(topic.id) + str(user.id) + form.cleaned_data.get('content')).hexdigest() 100 if last_replied_fingerprint == new_replied_fingerprint:
100 if last_replied_fingerprint == new_replied_fingerprint: 101 errors = {'duplicated_reply': [u'回复重复提交']}
101 errors = {'duplicated_reply': [u'回复重复提交']} 102 return get_view(request, topic.id, errors=errors)
102 return get_view(request, topic.id, errors=errors) 103
103 104 now = timezone.now()
104 now = timezone.now() 105 reply = Reply(
105 reply = Reply( 106 topic = topic,
106 topic = topic, 107 author = user,
107 author = user, 108 content = form.cleaned_data.get('content'),
108 content = form.cleaned_data.get('content'), 109 created = now,
109 created = now, 110 )
110 ) 111 reply.save()
111 reply.save() 112 Topic.objects.filter(pk=topic.id).update(last_replied_by=user, last_replied_time=now, last_touched=now)
112 Topic.objects.filter(pk=topic.id).update(last_replied_by=user, last_replied_time=now, last_touched=now) 113
113 114 notifications = []
114 notifications = [] 115 if user.id != topic.author.id:
115 if user.id != topic.author.id: 116 notification = Notification(
116 notification = Notification( 117 content = form.cleaned_data.get('content'),
117 content = form.cleaned_data.get('content'), 118 status = 0,
118 status = 0, 119 involved_type = 1, # 0: mention, 1: reply
119 involved_type = 1, # 0: mention, 1: reply 120 involved_user = topic.author,
120 involved_user = topic.author, 121 involved_topic = topic,
121 involved_topic = topic, 122 trigger_user = user,
122 trigger_user = user, 123 occurrence_time = now,
123 occurrence_time = now, 124 )
124 ) 125 notifications.append(notification)
125 notifications.append(notification) 126
126 127 mentions = find_mentions(form.cleaned_data.get('content'))
127 mentions = find_mentions(form.cleaned_data.get('content')) 128 if user.username in mentions:
128 if user.username in mentions: 129 mentions.remove(user.username)
129 mentions.remove(user.username) 130 if topic.author.username in mentions:
130 if topic.author.username in mentions: 131 mentions.remove(topic.author.username)
131 mentions.remove(topic.author.username) 132 if mentions:
132 if mentions: 133 mention_users = ForumUser.objects.filter(username__in=mentions)
133 mention_users = ForumUser.objects.filter(username__in=mentions) 134 if mention_users:
134 if mention_users: 135 for mention_user in mention_users:
135 for mention_user in mention_users: 136 notification = Notification(
136 notification = Notification( 137 content = form.cleaned_data.get('content'),
137 content = form.cleaned_data.get('content'), 138 status = 0,
138 status = 0, 139 involved_type = 0, # 0: mention, 1: reply
139 involved_type = 0, # 0: mention, 1: reply 140 involved_user = mention_user,
140 involved_user = mention_user, 141 involved_topic = topic,
141 involved_topic = topic, 142 trigger_user = user,
142 trigger_user = user, 143 occurrence_time = now,
143 occurrence_time = now, 144 )
144 ) 145 notifications.append(notification)
145 notifications.append(notification) 146 if notifications:
146 if notifications: 147 Notification.objects.bulk_create(notifications)
147 Notification.objects.bulk_create(notifications) 148
148 149 if user.id != topic.author.id:
149 if user.id != topic.author.id: 150 topic_time_diff = timezone.now() - topic.created
150 topic_time_diff = timezone.now() - topic.created 151 reputation = topic.author.reputation or 0
151 reputation = topic.author.reputation or 0 152 reputation = reputation + 2 * math.log(user.reputation or 0 + topic_time_diff.days + 10, 10)
152 reputation = reputation + 2 * math.log(user.reputation or 0 + topic_time_diff.days + 10, 10) 153 ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation)
153 ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) 154
154 155 return get_view(request, topic_id, errors=form.errors)
155 return get_view(request, topic_id, errors=form.errors) 156
156 157
157 158 @login_required
158 @login_required 159 def get_create(request, slug=None, errors=None):
159 def get_create(request, slug=None, errors=None): 160 node = get_object_or_404(Node, slug=slug)
160 node = get_object_or_404(Node, slug=slug) 161 user = request.user
161 user = request.user 162 counter = {
162 counter = { 163 'topics': user.topic_author.all().count(),
163 'topics': user.topic_author.all().count(), 164 'replies': user.reply_author.all().count(),
164 'replies': user.reply_author.all().count(), 165 'favorites': user.fav_user.all().count()
165 'favorites': user.fav_user.all().count() 166 }
166 } 167 notifications_count = user.notify_user.filter(status=0).count()
167 notifications_count = user.notify_user.filter(status=0).count() 168 node_slug = node.slug
168 node_slug = node.slug 169 active_page = 'topic'
169 active_page = 'topic' 170 return render_to_response('topic/create.html', locals(),
170 return render_to_response('topic/create.html', locals(), 171 context_instance=RequestContext(request))
171 context_instance=RequestContext(request)) 172
172 173
173 174 @login_required
174 @login_required 175 def post_create(request, slug=None):
175 def post_create(request, slug=None): 176 node = get_object_or_404(Node, slug=slug)
176 node = get_object_or_404(Node, slug=slug) 177
177 178 form = CreateForm(request.POST)
178 form = CreateForm(request.POST) 179 if not form.is_valid():
179 if not form.is_valid(): 180 return get_create(request, slug=slug, errors=form.errors)
180 return get_create(request, slug=slug, errors=form.errors) 181
181 182 user = request.user
182 user = request.user 183 try:
183 try: 184 last_created = user.topic_author.all().order_by('-created')[0]
184 last_created = user.topic_author.all().order_by('-created')[0] 185 except IndexError:
185 except IndexError: 186 last_created = None
186 last_created = None 187
187 188 if last_created: # 如果用户最后一篇的标题内容与提交的相同
188 if last_created: # 如果用户最后一篇的标题内容与提交的相同 189 last_created_fingerprint = hashlib.sha1(last_created.title + \
189 last_created_fingerprint = hashlib.sha1(last_created.title + \ 190 last_created.content + str(last_created.node_id)).hexdigest()
190 last_created.content + str(last_created.node_id)).hexdigest() 191 new_created_fingerprint = hashlib.sha1(form.cleaned_data.get('title') + \
191 new_created_fingerprint = hashlib.sha1(form.cleaned_data.get('title') + \ 192 form.cleaned_data.get('content') + str(node.id)).hexdigest()
192 form.cleaned_data.get('content') + str(node.id)).hexdigest() 193
193 194 if last_created_fingerprint == new_created_fingerprint:
194 if last_created_fingerprint == new_created_fingerprint: 195 errors = {'duplicated_topic': [u'帖子重复提交']}
195 errors = {'duplicated_topic': [u'帖子重复提交']} 196 return get_create(request, slug=slug, errors=errors)
196 return get_create(request, slug=slug, errors=errors) 197
197 198 now = timezone.now()
198 now = timezone.now() 199 topic = Topic(
199 topic = Topic( 200 title = form.cleaned_data.get('title'),
200 title = form.cleaned_data.get('title'), 201 content = form.cleaned_data.get('content'),
201 content = form.cleaned_data.get('content'), 202 created = now,
202 created = now, 203 node = node,
203 node = node, 204 author = user,
204 author = user, 205 reply_count = 0,
205 reply_count = 0, 206 last_touched = now,
206 last_touched = now, 207 )
207 ) 208 topic.save()
208 topic.save() 209
209 210 reputation = user.reputation or 0
210 reputation = user.reputation or 0 211 reputation = reputation - 5 # 每次发布话题扣除用户威望5点
211 reputation = reputation - 5 # 每次发布话题扣除用户威望5点 212 reputation = 0 if reputation < 0 else reputation
212 reputation = 0 if reputation < 0 else reputation 213 ForumUser.objects.filter(pk=user.id).update(reputation=reputation)
213 ForumUser.objects.filter(pk=user.id).update(reputation=reputation) 214
214 215 return redirect('/')
215 return redirect('/') 216
216 217
217 218 @login_required
218 @login_required 219 def get_edit(request, topic_id, errors=None):
219 def get_edit(request, topic_id, errors=None): 220 topic = get_object_or_404(Topic, pk=topic_id)
220 topic = get_object_or_404(Topic, pk=topic_id) 221
221 222 user = request.user
222 user = request.user 223 counter = {
223 counter = { 224 'topics': user.topic_author.all().count(),
224 'topics': user.topic_author.all().count(), 225 'replies': user.reply_author.all().count(),
225 'replies': user.reply_author.all().count(), 226 'favorites': user.fav_user.all().count()
226 'favorites': user.fav_user.all().count() 227 }
227 } 228 notifications_count = user.notify_user.filter(status=0).count()
228 notifications_count = user.notify_user.filter(status=0).count() 229
229 230 active_page = 'topic'
230 active_page = 'topic' 231 return render_to_response('topic/edit.html', locals(),
231 return render_to_response('topic/edit.html', locals(), 232 context_instance=RequestContext(request))
232 context_instance=RequestContext(request)) 233
233 234
234 235 @login_required
235 @login_required 236 def post_edit(request, topic_id):
236 def post_edit(request, topic_id): 237 topic = get_object_or_404(Topic, pk=topic_id)
237 topic = get_object_or_404(Topic, pk=topic_id) 238
238 239 form = CreateForm(request.POST)
239 form = CreateForm(request.POST) 240 if not form.is_valid():
240 if not form.is_valid(): 241 return get_edit(request, topic_id, errors=form.errors)
241 return get_edit(request, topic_id, errors=form.errors) 242
242 243 user = request.user
243 user = request.user 244 if topic.author_id != user.id:
244 if topic.author_id != user.id: 245 errors = {'invalid_permission': [u'没有权限修改该主题']}
245 errors = {'invalid_permission': [u'没有权限修改该主题']} 246 return get_edit(request, topic_id, errors=errors)
246 return get_edit(request, topic_id, errors=errors) 247
247 248 now = timezone.now()
248 now = timezone.now() 249 Topic.objects.filter(pk=topic.id).update(updated=now, last_touched=now, **form.cleaned_data)
249 Topic.objects.filter(pk=topic.id).update(updated=now, last_touched=now, **form.cleaned_data) 250
250 251 reputation = user.reputation or 0
251 reputation = user.reputation or 0 252 reputation = reputation - 2 # 每次修改回复扣除用户威望2点
252 reputation = reputation - 2 # 每次修改回复扣除用户威望2点 253 reputation = 0 if reputation < 0 else reputation
253 reputation = 0 if reputation < 0 else reputation 254 ForumUser.objects.filter(pk=user.id).update(reputation=reputation)
254 ForumUser.objects.filter(pk=user.id).update(reputation=reputation) 255
255 256 return redirect('/t/%s/' % topic.id)
256 return redirect('/t/%s/' % topic.id) 257
257 258
258 259 @login_required
259 @login_required 260 def get_reply_edit(request, reply_id, errors=None):
260 def get_reply_edit(request, reply_id, errors=None): 261 reply = get_object_or_404(Reply, pk=reply_id)
261 reply = get_object_or_404(Reply, pk=reply_id) 262 user = request.user
262 user = request.user 263 counter = {
263 counter = { 264 'topics': user.topic_author.all().count(),
264 'topics': user.topic_author.all().count(), 265 'replies': user.reply_author.all().count(),
265 'replies': user.reply_author.all().count(), 266 'favorites': user.fav_user.all().count()
266 'favorites': user.fav_user.all().count() 267 }
267 } 268 notifications_count = user.notify_user.filter(status=0).count()
268 notifications_count = user.notify_user.filter(status=0).count() 269 active_page = 'topic'
269 active_page = 'topic' 270 return render_to_response('topic/reply_edit.html', locals(),
270 return render_to_response('topic/reply_edit.html', locals(), 271 context_instance=RequestContext(request))
271 context_instance=RequestContext(request)) 272
272 273
273 274 @login_required
274 @login_required 275 def post_reply_edit(request, reply_id):
275 def post_reply_edit(request, reply_id): 276 reply = get_object_or_404(Reply, pk=reply_id)
276 reply = get_object_or_404(Reply, pk=reply_id) 277
277 278 form = ReplyForm(request.POST)
278 form = ReplyForm(request.POST) 279 if not form.is_valid():
279 if not form.is_valid(): 280 return get_reply_edit(request, reply_id, errors=form.errors)
280 return get_reply_edit(request, reply_id, errors=form.errors) 281
281 282 user = request.user
282 user = request.user 283 if reply.author_id != user.id:
283 if reply.author_id != user.id: 284 errors = {'invalid_permission': [u'没有权限修改该回复']}
284 errors = {'invalid_permission': [u'没有权限修改该回复']} 285 return get_reply_edit(request, reply_id, errors=errors)
285 return get_reply_edit(request, reply_id, errors=errors) 286
286 287 Reply.objects.filter(pk=reply.id).update(updated=timezone.now(), **form.cleaned_data)
287 Reply.objects.filter(pk=reply.id).update(updated=timezone.now(), **form.cleaned_data) 288
288 289 reputation = user.reputation or 0
289 reputation = user.reputation or 0 290 reputation = reputation - 2 # 每次修改回复扣除用户威望2点
290 reputation = reputation - 2 # 每次修改回复扣除用户威望2点 291 reputation = 0 if reputation < 0 else reputation
291 reputation = 0 if reputation < 0 else reputation 292 ForumUser.objects.filter(pk=user.id).update(reputation=reputation)
292 ForumUser.objects.filter(pk=user.id).update(reputation=reputation) 293
293 294 return redirect('/t/%s/' % reply.topic_id)
294 return redirect('/t/%s/' % reply.topic_id) 295
295 296
296 297 def get_node_topics(request, slug):
297 def get_node_topics(request, slug): 298 node = get_object_or_404(Node, slug=slug)
298 node = get_object_or_404(Node, slug=slug) 299
299 300 user = request.user
300 user = request.user 301 if user.is_authenticated():
301 if user.is_authenticated(): 302 counter = {
302 counter = { 303 'topics': user.topic_author.all().count(),
303 'topics': user.topic_author.all().count(), 304 'replies': user.reply_author.all().count(),
304 'replies': user.reply_author.all().count(), 305 'favorites': user.fav_user.all().count()
305 'favorites': user.fav_user.all().count() 306 }
306 } 307 notifications_count = user.notify_user.filter(status=0).count()
307 notifications_count = user.notify_user.filter(status=0).count() 308
308 309 try:
309 try: 310 current_page = int(request.GET.get('p', '1'))
310 current_page = int(request.GET.get('p', '1')) 311 except ValueError:
311 except ValueError: 312 current_page = 1
312 current_page = 1 313
313 314 topics, topic_page = Topic.objects.get_all_topics_by_node_slug(node_slug=slug, current_page=current_page)
314 topics, topic_page = Topic.objects.get_all_topics_by_node_slug(node_slug=slug, current_page=current_page) 315 active_page = 'topic'
315 active_page = 'topic' 316 return render_to_response('topic/node_topics.html', locals(),
316 return render_to_response('topic/node_topics.html', locals(), 317 context_instance=RequestContext(request))
317 context_instance=RequestContext(request)) 318
318 319
319 320 def get_user_topics(request, uid):
320 def get_user_topics(request, uid): 321 try:
321 try: 322 if uid.isdigit():
322 if uid.isdigit(): 323 user_info = ForumUser.objects.get(pk=uid)
323 user_info = ForumUser.objects.get(pk=uid) 324 else:
324 else: 325 user_info = ForumUser.objects.get(username=uid)
325 user_info = ForumUser.objects.get(username=uid) 326 except ForumUser.DoesNotExist:
326 except ForumUser.DoesNotExist: 327 raise Http404
327 raise Http404 328
328 329 try:
329 try: 330 current_page = int(request.GET.get('p', '1'))
330 current_page = int(request.GET.get('p', '1')) 331 except ValueError:
331 except ValueError: 332 current_page = 1
332 current_page = 1 333
333 334 counter = {
334 counter = { 335 'topics': user_info.topic_author.all().count(),
335 'topics': user_info.topic_author.all().count(), 336 'replies': user_info.reply_author.all().count(),
336 'replies': user_info.reply_author.all().count(), 337 'favorites': user_info.fav_user.all().count()
337 'favorites': user_info.fav_user.all().count() 338 }
338 } 339
339 340 user = request.user
340 user = request.user 341 if user.is_authenticated():
341 if user.is_authenticated(): 342 notifications_count = user.notify_user.filter(status=0).count()
342 notifications_count = user.notify_user.filter(status=0).count() 343
343 344 topics, topic_page = Topic.objects.get_user_all_topics(user_info.id, current_page=current_page)
344 topics, topic_page = Topic.objects.get_user_all_topics(user_info.id, current_page=current_page) 345 active_page = 'topic'
345 active_page = 'topic' 346 return render_to_response('topic/user_topics.html', locals(),
346 return render_to_response('topic/user_topics.html', locals(), 347 context_instance=RequestContext(request))
347 context_instance=RequestContext(request)) 348
348 349
349 350 def get_user_replies(request, uid):
350 def get_user_replies(request, uid): 351 try:
351 try: 352 if uid.isdigit():
352 if uid.isdigit(): 353 user_info = ForumUser.objects.get(pk=uid)
353 user_info = ForumUser.objects.get(pk=uid) 354 else:
354 else: 355 user_info = ForumUser.objects.get(username=uid)
355 user_info = ForumUser.objects.get(username=uid) 356 except ForumUser.DoesNotExist:
356 except ForumUser.DoesNotExist: 357 raise Http404
357 raise Http404 358
358 359 try:
359 try: 360 current_page = int(request.GET.get('p', '1'))
360 current_page = int(request.GET.get('p', '1')) 361 except ValueError:
361 except ValueError: 362 current_page = 1
362 current_page = 1 363
363 364 counter = {
364 counter = { 365 'topics': user_info.topic_author.all().count(),
365 'topics': user_info.topic_author.all().count(), 366 'replies': user_info.reply_author.all().count(),
366 'replies': user_info.reply_author.all().count(), 367 'favorites': user_info.fav_user.all().count()
367 'favorites': user_info.fav_user.all().count() 368 }
368 } 369
369 370 user = request.user
370 user = request.user 371 if user.is_authenticated():
371 if user.is_authenticated(): 372 notifications_count = user.notify_user.filter(status=0).count()
372 notifications_count = user.notify_user.filter(status=0).count() 373
373 374 replies, reply_page = Reply.objects.get_user_all_replies(user_info.id, current_page=current_page)
374 replies, reply_page = Reply.objects.get_user_all_replies(user_info.id, current_page=current_page) 375 active_page = 'topic'
375 active_page = 'topic' 376 return render_to_response('topic/user_replies.html', locals(),
376 return render_to_response('topic/user_replies.html', locals(), 377 context_instance=RequestContext(request))
377 context_instance=RequestContext(request)) 378
378 379
379 380 def get_user_favorites(request, uid):
380 def get_user_favorites(request, uid): 381 try:
381 try: 382 if uid.isdigit():
382 if uid.isdigit(): 383 user_info = ForumUser.objects.get(pk=uid)
383 user_info = ForumUser.objects.get(pk=uid) 384 else:
384 else: 385 user_info = ForumUser.objects.get(username=uid)
385 user_info = ForumUser.objects.get(username=uid) 386 except ForumUser.DoesNotExist:
386 except ForumUser.DoesNotExist: 387 raise Http404
387 raise Http404 388
388 389 try:
389 try: 390 current_page = int(request.GET.get('p', '1'))
390 current_page = int(request.GET.get('p', '1')) 391 except ValueError:
391 except ValueError: 392 current_page = 1
392 current_page = 1 393
393 394 counter = {
394 counter = { 395 'topics': user_info.topic_author.all().count(),
395 'topics': user_info.topic_author.all().count(), 396 'replies': user_info.reply_author.all().count(),
396 'replies': user_info.reply_author.all().count(), 397 'favorites': user_info.fav_user.all().count()
397 'favorites': user_info.fav_user.all().count() 398 }
398 } 399
399 400 user = request.user
400 user = request.user 401 if user.is_authenticated():
401 if user.is_authenticated(): 402 notifications_count = user.notify_user.filter(status=0).count()
402 notifications_count = user.notify_user.filter(status=0).count() 403
403 404 favorites, favorite_page = Favorite.objects.get_user_all_favorites(user_info.id, current_page=current_page)
404 favorites, favorite_page = Favorite.objects.get_user_all_favorites(user_info.id, current_page=current_page) 405 active_page = 'topic'
405 active_page = 'topic' 406 return render_to_response('topic/user_favorites.html', locals(),
406 return render_to_response('topic/user_favorites.html', locals(), 407 context_instance=RequestContext(request))
407 context_instance=RequestContext(request)) 408
408 409
409 410 def get_profile(request, uid):
410 def get_profile(request, uid): 411 try:
411 try: 412 if uid.isdigit():
412 if uid.isdigit(): 413 user_info = ForumUser.objects.get(pk=uid)
413 user_info = ForumUser.objects.get(pk=uid) 414 else:
414 else: 415 user_info = ForumUser.objects.get(username=uid)
415 user_info = ForumUser.objects.get(username=uid) 416 except ForumUser.DoesNotExist:
416 except ForumUser.DoesNotExist: 417 raise Http404
417 raise Http404 418
418 419 try:
419 try: 420 current_page = int(request.GET.get('p', '1'))
420 current_page = int(request.GET.get('p', '1')) 421 except ValueError:
421 except ValueError: 422 current_page = 1
422 current_page = 1 423
423 424 counter = {
424 counter = { 425 'topics': user_info.topic_author.all().count(),
425 'topics': user_info.topic_author.all().count(), 426 'replies': user_info.reply_author.all().count(),
426 'replies': user_info.reply_author.all().count(), 427 'favorites': user_info.fav_user.all().count()
427 'favorites': user_info.fav_user.all().count() 428 }
428 } 429
429 430 user = request.user
430 user = request.user 431 if user.is_authenticated():
431 if user.is_authenticated(): 432 notifications_count = user.notify_user.filter(status=0).count()
432 notifications_count = user.notify_user.filter(status=0).count() 433
433 434 topics, topic_page = Topic.objects.get_user_all_topics(user_info.id, current_page=current_page)
434 topics, topic_page = Topic.objects.get_user_all_topics(user_info.id, current_page=current_page) 435 replies, reply_page = Reply.objects.get_user_all_replies(user_info.id, current_page=current_page)
435 replies, reply_page = Reply.objects.get_user_all_replies(user_info.id, current_page=current_page) 436 active_page = '_blank'
436 active_page = '_blank' 437 return render_to_response('topic/profile.html', locals(),
437 return render_to_response('topic/profile.html', locals(), 438 context_instance=RequestContext(request))
438 context_instance=RequestContext(request)) 439
439 440
440 441 def get_vote(request):
441 def get_vote(request): 442 user = request.user
442 user = request.user 443 if not user.is_authenticated():
443 if not user.is_authenticated(): 444 return HttpResponse(json.dumps({
444 return HttpResponse(json.dumps({ 445 'success': 0,
445 'success': 0, 446 'message': 'user_not_login'
446 'message': 'user_not_login' 447 }), content_type='application/json')
447 }), content_type='application/json') 448
448 449 try:
449 try: 450 topic_id = int(request.GET.get('topic_id'))
450 topic_id = int(request.GET.get('topic_id')) 451 except (TypeError, ValueError):
451 except (TypeError, ValueError): 452 topic_id = None
452 topic_id = None 453 topic = None
453 topic = None 454 if topic_id:
454 if topic_id: 455 try:
455 try: 456 topic = Topic.objects.select_related('author').get(pk=topic_id)
456 topic = Topic.objects.select_related('author').get(pk=topic_id) 457 except Topic.DoesNotExist:
457 except Topic.DoesNotExist: 458 pass
458 pass 459
459 460 if not (topic_id and topic):
460 if not (topic_id and topic): 461 return HttpResponse(json.dumps({
461 return HttpResponse(json.dumps({ 462 'success': 0,
462 'success': 0, 463 'message': 'topic_not_exist'
463 'message': 'topic_not_exist' 464 }), content_type='application/json')
464 }), content_type='application/json') 465
465 466 if user.id == topic.author.id:
466 if user.id == topic.author.id: 467 return HttpResponse(json.dumps({
467 return HttpResponse(json.dumps({ 468 'success': 0,
468 'success': 0, 469 'message': 'can_not_vote_your_topic'
469 'message': 'can_not_vote_your_topic' 470 }), content_type='application/json')
470 }), content_type='application/json') 471
471 472 if Vote.objects.filter(trigger_user=user, involved_topic=topic).exists():
472 if Vote.objects.filter(trigger_user=user, involved_topic=topic).exists(): 473 return HttpResponse(json.dumps({
473 return HttpResponse(json.dumps({ 474 'success': 0,
474 'success': 0, 475 'message': 'already_voted'
475 'message': 'already_voted' 476 }), content_type='application/json')
476 }), content_type='application/json') 477
477 478 vote = Vote(trigger_user=user, involved_type=0, involved_topic=topic, \
478 vote = Vote(trigger_user=user, involved_type=0, involved_topic=topic, \ 479 involved_user=topic.author, status=0, occurrence_time=timezone.now())
479 involved_user=topic.author, status=0, occurrence_time=timezone.now()) 480 vote.save()
480 vote.save() 481
481 482 # 更新话题作者声誉
482 # 更新话题作者声誉 483 topic_time_diff = timezone.now() - topic.created
483 topic_time_diff = timezone.now() - topic.created 484 reputation = topic.author.reputation or 0
484 reputation = topic.author.reputation or 0 485 reputation = reputation + 2 * math.log((user.reputation or 0) + topic_time_diff.days + 10, 10)
485 reputation = reputation + 2 * math.log((user.reputation or 0) + topic_time_diff.days + 10, 10) 486 ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation)
486 ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) 487
487 488 return HttpResponse(json.dumps({
488 return HttpResponse(json.dumps({ 489 'success': 1,
489 'success': 1, 490 'message': 'thanks_for_your_vote'
490 'message': 'thanks_for_your_vote' 491 }), content_type='application/json')
491 }), content_type='application/json') 492
492 493
493 494 def get_favorite(request):
494 def get_favorite(request): 495 user = request.user
495 user = request.user 496 if not user.is_authenticated():
496 if not user.is_authenticated(): 497 return HttpResponse(json.dumps({
497 return HttpResponse(json.dumps({ 498 'success': 0,
498 'success': 0, 499 'message': 'user_not_login'
499 'message': 'user_not_login' 500 }), content_type='application/json')
500 }), content_type='application/json') 501
501 502 try:
502 try: 503 topic_id = int(request.GET.get('topic_id'))
503 topic_id = int(request.GET.get('topic_id')) 504 except (TypeError, ValueError):
504 except (TypeError, ValueError): 505 topic_id = None
505 topic_id = None 506 topic = None
506 topic = None 507 if topic_id:
507 if topic_id: 508 try:
508 try: 509 topic = Topic.objects.select_related('author').get(pk=topic_id)
509 topic = Topic.objects.select_related('author').get(pk=topic_id) 510 except Topic.DoesNotExist:
510 except Topic.DoesNotExist: 511 pass
511 pass 512
512 513 if not (topic_id and topic):
513 if not (topic_id and topic): 514 return HttpResponse(json.dumps({
514 return HttpResponse(json.dumps({ 515 'success': 0,
515 'success': 0, 516 'message': 'topic_not_exist'
516 'message': 'topic_not_exist' 517 }), content_type='application/json')
517 }), content_type='application/json') 518
518 519 if user.id == topic.author.id:
519 if user.id == topic.author.id: 520 return HttpResponse(json.dumps({
520 return HttpResponse(json.dumps({ 521 'success': 0,
521 'success': 0, 522 'message': 'can_not_favorite_your_topic'
522 'message': 'can_not_favorite_your_topic' 523 }), content_type='application/json')
523 }), content_type='application/json') 524
524 525 if Favorite.objects.filter(owner_user=user, involved_topic=topic).exists():
525 if Favorite.objects.filter(owner_user=user, involved_topic=topic).exists(): 526 return HttpResponse(json.dumps({
526 return HttpResponse(json.dumps({ 527 'success': 0,
527 'success': 0, 528 'message': 'already_favorited'
528 'message': 'already_favorited' 529 }), content_type='application/json')
529 }), content_type='application/json') 530
530 531 favorite = Favorite(owner_user=user, involved_type=0, involved_topic=topic, created=timezone.now())
531 favorite = Favorite(owner_user=user, involved_type=0, involved_topic=topic, created=timezone.now()) 532 favorite.save()
532 favorite.save() 533
533 534 # 更新话题作者声誉
534 # 更新话题作者声誉 535 topic_time_diff = timezone.now() - topic.created
535 topic_time_diff = timezone.now() - topic.created 536 reputation = topic.author.reputation or 0
536 reputation = topic.author.reputation or 0 537 reputation = reputation + 2 * math.log((user.reputation or 0) + topic_time_diff.days + 10, 10)
537 reputation = reputation + 2 * math.log((user.reputation or 0) + topic_time_diff.days + 10, 10) 538 ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation)
538 ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) 539
539 540 return HttpResponse(json.dumps({
540 return HttpResponse(json.dumps({ 541 'success': 1,
541 'success': 1, 542 'message': 'cancel_favorite_success'
542 'message': 'cancel_favorite_success' 543 }), content_type='application/json')
543 }), content_type='application/json') 544
544 545
545 546 def get_cancel_favorite(request):
546 def get_cancel_favorite(request): 547 user = request.user
547 user = request.user 548 if not user.is_authenticated():
548 if not user.is_authenticated(): 549 return HttpResponse(json.dumps({
549 return HttpResponse(json.dumps({ 550 'success': 0,
550 'success': 0, 551 'message': 'user_not_login'
551 'message': 'user_not_login' 552 }), content_type='application/json')
552 }), content_type='application/json') 553
553 554 try:
554 try: 555 topic_id = int(request.GET.get('topic_id'))
555 topic_id = int(request.GET.get('topic_id')) 556 except (TypeError, ValueError):
556 except (TypeError, ValueError): 557 topic_id = None
557 topic_id = None 558 topic = None
558 topic = None 559 if topic_id:
559 if topic_id: 560 try:
560 try: 561 topic = Topic.objects.select_related('author').get(pk=topic_id)
561 topic = Topic.objects.select_related('author').get(pk=topic_id) 562 except Topic.DoesNotExist:
562 except Topic.DoesNotExist: 563 pass
563 pass 564
564 565 if not (topic_id and topic):
565 if not (topic_id and topic): 566 return HttpResponse(json.dumps({
566 return HttpResponse(json.dumps({ 567 'success': 0,
567 'success': 0, 568 'message': 'topic_not_exist'
568 'message': 'topic_not_exist' 569 }), content_type='application/json')
569 }), content_type='application/json') 570
570 571 try:
571 try: 572 favorite = Favorite.objects.get(owner_user=user, involved_topic=topic)
572 favorite = Favorite.objects.get(owner_user=user, involved_topic=topic) 573 except Favorite.DoesNotExist:
573 except Favorite.DoesNotExist: 574 favorite = None
574 favorite = None 575
575 576 if not favorite:
576 if not favorite: 577 return HttpResponse(json.dumps({
577 return HttpResponse(json.dumps({ 578 'success': 0,
578 'success': 0, 579 'message': 'not_been_favorited'
579 'message': 'not_been_favorited' 580 }), content_type='application/json')
580 }), content_type='application/json') 581
581 582 favorite.delete()
582 favorite.delete() 583
583 584 # 更新话题作者声誉
584 # 更新话题作者声誉 585 topic_time_diff = timezone.now() - topic.created
585 topic_time_diff = timezone.now() - topic.created 586 reputation = topic.author.reputation or 0
586 reputation = topic.author.reputation or 0 587 reputation = reputation - math.log(user.reputation or 0 + topic_time_diff.days + 10, 15)
587 reputation = reputation - math.log(user.reputation or 0 + topic_time_diff.days + 10, 15) 588 ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation)
588 ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) 589
589 590 return HttpResponse(json.dumps({
590 return HttpResponse(json.dumps({ 591 'success': 1,
591 'success': 1, 592 'message': 'cancel_favorite_success'
592 'message': 'cancel_favorite_success' 593 }), content_type='application/json')
593 }), content_type='application/json') 594
594 595
595 596 def get_members(request):
596 def get_members(request): 597 user = request.user
597 user = request.user 598 if user.is_authenticated():
598 if user.is_authenticated(): 599 counter = {
599 counter = { 600 'topics': user.topic_author.all().count(),
600 'topics': user.topic_author.all().count(), 601 'replies': user.reply_author.all().count(),
601 'replies': user.reply_author.all().count(), 602 'favorites': user.fav_user.all().count()
602 'favorites': user.fav_user.all().count() 603 }
603 } 604 notifications_count = user.notify_user.filter(status=0).count()
604 notifications_count = user.notify_user.filter(status=0).count() 605
605 606 members = ForumUser.objects.all().order_by('-id')[:49]
606 members = ForumUser.objects.all().order_by('-id')[:49] 607 active_members = ForumUser.objects.all().order_by('-last_login')[:49]
607 active_members = ForumUser.objects.all().order_by('-last_login')[:49] 608 active_page = 'members'
608 active_page = 'members' 609 return render_to_response('topic/members.html', locals(),
609 return render_to_response('topic/members.html', locals(), 610 context_instance=RequestContext(request))
610 context_instance=RequestContext(request)) 611
1 # coding: utf-8 1 # coding: utf-8
2 # Django settings for xp project. 2 # Django settings for xp project.
3 3
4 DEBUG = True 4 DEBUG = True
5 TEMPLATE_DEBUG = DEBUG 5 TEMPLATE_DEBUG = DEBUG
6 6
7 ADMINS = ( 7 ADMINS = (
8 # ('Your Name', 'your_email@example.com'), 8 # ('Your Name', 'your_email@example.com'),
9 ) 9 )
10 10
11 MANAGERS = ADMINS 11 MANAGERS = ADMINS
12 12
13 DATABASES = { 13 DATABASES = {
14 'default': { 14 'default': {
15 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. 15 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
16 'NAME': 'forum', # Or path to database file if using sqlite3. 16 'NAME': 'forum', # Or path to database file if using sqlite3.
17 # The following settings are not used with sqlite3: 17 # The following settings are not used with sqlite3:
18 'USER': 'root', 18 'USER': 'root',
19 'PASSWORD': 'nineteen', 19 'PASSWORD': 'nineteen',
20 'HOST': '127.0.0.1', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. 20 'HOST': '127.0.0.1', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
21 'PORT': '3306', # Set to empty string for default. 21 'PORT': '3306', # Set to empty string for default.
22 } 22 }
23 } 23 }
24 24
25 # Hosts/domain names that are valid for this site; required if DEBUG is False 25 # Hosts/domain names that are valid for this site; required if DEBUG is False
26 # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts 26 # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
27 ALLOWED_HOSTS = ['*'] 27 ALLOWED_HOSTS = ['*']
28 28
29 # Local time zone for this installation. Choices can be found here: 29 # Local time zone for this installation. Choices can be found here:
30 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 30 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
31 # although not all choices may be available on all operating systems. 31 # although not all choices may be available on all operating systems.
32 # In a Windows environment this must be set to your system time zone. 32 # In a Windows environment this must be set to your system time zone.
33 TIME_ZONE = 'Asia/Shanghai' 33 TIME_ZONE = 'Asia/Shanghai'
34 34
35 # Language code for this installation. All choices can be found here: 35 # Language code for this installation. All choices can be found here:
36 # http://www.i18nguy.com/unicode/language-identifiers.html 36 # http://www.i18nguy.com/unicode/language-identifiers.html
37 LANGUAGE_CODE = 'zh-CN' 37 LANGUAGE_CODE = 'zh-CN'
38 38
39 SITE_ID = 1 39 SITE_ID = 1
40 40
41 # If you set this to False, Django will make some optimizations so as not 41 # If you set this to False, Django will make some optimizations so as not
42 # to load the internationalization machinery. 42 # to load the internationalization machinery.
43 USE_I18N = True # 只有用admin的时候需要开启 43 USE_I18N = True # 只有用admin的时候需要开启
44 44
45 # If you set this to False, Django will not format dates, numbers and 45 # If you set this to False, Django will not format dates, numbers and
46 # calendars according to the current locale. 46 # calendars according to the current locale.
47 USE_L10N = False 47 USE_L10N = False
48 48
49 # If you set this to False, Django will not use timezone-aware datetimes. 49 # If you set this to False, Django will not use timezone-aware datetimes.
50 USE_TZ = False 50 USE_TZ = False
51 51
52 # Absolute filesystem path to the directory that will hold user-uploaded files. 52 # Absolute filesystem path to the directory that will hold user-uploaded files.
53 # Example: "/var/www/example.com/media/" 53 # Example: "/var/www/example.com/media/"
54 MEDIA_ROOT = '' 54 MEDIA_ROOT = ''
55 55
56 # URL that handles the media served from MEDIA_ROOT. Make sure to use a 56 # URL that handles the media served from MEDIA_ROOT. Make sure to use a
57 # trailing slash. 57 # trailing slash.
58 # Examples: "http://example.com/media/", "http://media.example.com/" 58 # Examples: "http://example.com/media/", "http://media.example.com/"
59 MEDIA_URL = '' 59 MEDIA_URL = ''
60 60
61 # Absolute path to the directory static files should be collected to. 61 # Absolute path to the directory static files should be collected to.
62 # Don't put anything in this directory yourself; store your static files 62 # Don't put anything in this directory yourself; store your static files
63 # in apps' "static/" subdirectories and in STATICFILES_DIRS. 63 # in apps' "static/" subdirectories and in STATICFILES_DIRS.
64 # Example: "/var/www/example.com/static/" 64 # Example: "/var/www/example.com/static/"
65 STATIC_ROOT = '' 65 STATIC_ROOT = ''
66 66
67 # URL prefix for static files. 67 # URL prefix for static files.
68 # Example: "http://example.com/static/", "http://static.example.com/" 68 # Example: "http://example.com/static/", "http://static.example.com/"
69 STATIC_URL = '/static/' 69 STATIC_URL = '/static/'
70 70
71 # Additional locations of static files 71 # Additional locations of static files
72 STATICFILES_DIRS = ( 72 STATICFILES_DIRS = (
73 # Put strings here, like "/home/html/static" or "C:/www/django/static". 73 # Put strings here, like "/home/html/static" or "C:/www/django/static".
74 # Always use forward slashes, even on Windows. 74 # Always use forward slashes, even on Windows.
75 # Don't forget to use absolute paths, not relative paths. 75 # Don't forget to use absolute paths, not relative paths.
76 ) 76 )
77 77
78 # List of finder classes that know how to find static files in 78 # List of finder classes that know how to find static files in
79 # various locations. 79 # various locations.
80 STATICFILES_FINDERS = ( 80 STATICFILES_FINDERS = (
81 'django.contrib.staticfiles.finders.FileSystemFinder', 81 'django.contrib.staticfiles.finders.FileSystemFinder',
82 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 82 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
83 # 'django.contrib.staticfiles.finders.DefaultStorageFinder', 83 # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
84 ) 84 )
85 85
86 # Make this unique, and don't share it with anybody. 86 # Make this unique, and don't share it with anybody.
87 SECRET_KEY = 'h6=yzee&jze#4p1@twhksg1wg6hv%pzwomw(!o($qsly%lzlhe' 87 SECRET_KEY = 'h6=yzee&jze#4p1@twhksg1wg6hv%pzwomw(!o($qsly%lzlhe'
88 88
89 # List of callables that know how to import templates from various sources. 89 # List of callables that know how to import templates from various sources.
90 TEMPLATE_LOADERS = ( 90 TEMPLATE_LOADERS = (
91 'django.template.loaders.filesystem.Loader', 91 'django.template.loaders.filesystem.Loader',
92 'django.template.loaders.app_directories.Loader', 92 'django.template.loaders.app_directories.Loader',
93 # 'django.template.loaders.eggs.Loader', 93 # 'django.template.loaders.eggs.Loader',
94 ) 94 )
95 95
96 MIDDLEWARE_CLASSES = ( 96 MIDDLEWARE_CLASSES = (
97 'django.middleware.cache.UpdateCacheMiddleware', # 缓存中间件,必须放在开头
98 'django.middleware.common.CommonMiddleware', 97 'django.middleware.common.CommonMiddleware',
99 'django.contrib.sessions.middleware.SessionMiddleware', 98 'django.contrib.sessions.middleware.SessionMiddleware',
100 'django.middleware.csrf.CsrfViewMiddleware', # 开启了CSRF,记得在POST表单中加{% csrf_token %},使用RequestContext 99 'django.middleware.csrf.CsrfViewMiddleware', # 开启了CSRF,记得在POST表单中加{% csrf_token %},使用RequestContext
101 'django.contrib.auth.middleware.AuthenticationMiddleware', 100 'django.contrib.auth.middleware.AuthenticationMiddleware',
102 'django.contrib.messages.middleware.MessageMiddleware', 101 'django.contrib.messages.middleware.MessageMiddleware',
103 # Uncomment the next line for simple clickjacking protection: 102 # Uncomment the next line for simple clickjacking protection:
104 # 'django.middleware.clickjacking.XFrameOptionsMiddleware', 103 # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
105 'django.middleware.cache.FetchFromCacheMiddleware', # 缓存中间件,必须放在最后 104 'django.middleware.cache.FetchFromCacheMiddleware', # 缓存中间件,必须放在最后
106 ) 105 )
107 106
108 ROOT_URLCONF = 'xp.urls' 107 ROOT_URLCONF = 'xp.urls'
109 108
110 # Python dotted path to the WSGI application used by Django's runserver. 109 # Python dotted path to the WSGI application used by Django's runserver.
111 WSGI_APPLICATION = 'xp.wsgi.application' 110 WSGI_APPLICATION = 'xp.wsgi.application'
112 111
113 TEMPLATE_DIRS = ( 112 TEMPLATE_DIRS = (
114 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 113 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
115 # Always use forward slashes, even on Windows. 114 # Always use forward slashes, even on Windows.
116 # Don't forget to use absolute paths, not relative paths. 115 # Don't forget to use absolute paths, not relative paths.
117 ) 116 )
118 117
119 TEMPLATE_CONTEXT_PROCESSORS = ( # F2E中有current_user对象和request对象,这里设置可在模板中使用RquestContext 118 TEMPLATE_CONTEXT_PROCESSORS = ( # F2E中有current_user对象和request对象,这里设置可在模板中使用RquestContext
120 'django.contrib.auth.context_processors.auth', # user对象等等 119 'django.contrib.auth.context_processors.auth', # user对象等等
121 'django.core.context_processors.request', # request对象等等 120 'django.core.context_processors.request', # request对象等等
122 'django.core.context_processors.static', # 在模板中使用{{ STATIC_URL }}获取静态文件路径 121 'django.core.context_processors.static', # 在模板中使用{{ STATIC_URL }}获取静态文件路径
123 'forum.context_processors.custom_proc', # 自定义模板上下文处理器 122 'forum.context_processors.custom_proc', # 自定义模板上下文处理器
124 ) 123 )
125 124
126 INSTALLED_APPS = ( 125 INSTALLED_APPS = (
127 'django.contrib.auth', 126 'django.contrib.auth',
128 'django.contrib.contenttypes', 127 'django.contrib.contenttypes',
129 'django.contrib.sessions', 128 'django.contrib.sessions',
130 'django.contrib.sites', 129 'django.contrib.sites',
131 'django.contrib.messages', 130 'django.contrib.messages',
132 'django.contrib.staticfiles', 131 'django.contrib.staticfiles',
133 # Uncomment the next line to enable the admin: 132 # Uncomment the next line to enable the admin:
134 'django.contrib.admin', 133 'django.contrib.admin',
135 # Uncomment the next line to enable admin documentation: 134 # Uncomment the next line to enable admin documentation:
136 # 'django.contrib.admindocs', 135 # 'django.contrib.admindocs',
137 'django.contrib.sitemaps', # Django sitemap framework 136 'django.contrib.sitemaps', # Django sitemap framework
138 'forum', 137 'forum',
139 ) 138 )
140 139
141 # A sample logging configuration. The only tangible logging 140 # A sample logging configuration. The only tangible logging
142 # performed by this configuration is to send an email to 141 # performed by this configuration is to send an email to
143 # the site admins on every HTTP 500 error when DEBUG=False. 142 # the site admins on every HTTP 500 error when DEBUG=False.
144 # See http://docs.djangoproject.com/en/dev/topics/logging for 143 # See http://docs.djangoproject.com/en/dev/topics/logging for
145 # more details on how to customize your logging configuration. 144 # more details on how to customize your logging configuration.
146 LOGGING = { 145 LOGGING = {
147 'version': 1, 146 'version': 1,
148 'disable_existing_loggers': False, 147 'disable_existing_loggers': False,
149 'filters': { 148 'filters': {
150 'require_debug_false': { 149 'require_debug_false': {
151 '()': 'django.utils.log.RequireDebugFalse' 150 '()': 'django.utils.log.RequireDebugFalse'
152 } 151 }
153 }, 152 },
154 'handlers': { 153 'handlers': {
155 'mail_admins': { 154 'mail_admins': {
156 'level': 'ERROR', 155 'level': 'ERROR',
157 'filters': ['require_debug_false'], 156 'filters': ['require_debug_false'],
158 'class': 'django.utils.log.AdminEmailHandler' 157 'class': 'django.utils.log.AdminEmailHandler'
159 }, 158 },
160 'console': { 159 'console': {
161 'level': 'DEBUG', 160 'level': 'DEBUG',
162 'class': 'logging.StreamHandler', 161 'class': 'logging.StreamHandler',
163 }, 162 },
164 }, 163 },
165 'loggers': { 164 'loggers': {
166 'django.request': { 165 'django.request': {
167 'handlers': ['mail_admins'], 166 'handlers': ['mail_admins'],
168 'level': 'ERROR', 167 'level': 'ERROR',
169 'propagate': True, 168 'propagate': True,
170 }, 169 },
171 'django.db.backends': { 170 'django.db.backends': {
172 'level': 'DEBUG', 171 'level': 'DEBUG',
173 'handlers': ['console'], 172 'handlers': ['console'],
174 }, 173 },
175 } 174 }
176 } 175 }
177 # 176 #
178 # CACHES = { # memcached缓存设置 177 # CACHES = { # memcached缓存设置
179 # 'default': { 178 # 'default': {
180 # 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 179 # 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
181 # 'LOCATION': '127.0.0.1:11211', 180 # 'LOCATION': '127.0.0.1:11211',
182 # } 181 # }
183 # } 182 # }
184 183
185 # SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 使用memcached存储session 184 # SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 使用memcached存储session
186 185
187 # 自定义User类 186 # 自定义User类
188 AUTH_USER_MODEL = 'forum.ForumUser' 187 AUTH_USER_MODEL = 'forum.ForumUser'
189 188
190 # 用户认证BackEnds 189 # 用户认证BackEnds
191 # AUTHENTICATION_BACKENDS = ('forum.backends.EmailAuthBackend',) 190 # AUTHENTICATION_BACKENDS = ('forum.backends.EmailAuthBackend',)
192 191
193 # 默认登陆uri 192 # 默认登陆uri
194 LOGIN_URL = '/login/' 193 LOGIN_URL = '/login/'
195 194
196 # 发送邮件设置 195 # 发送邮件设置
197 EMAIL_HOST = 'smtp.qq.com' 196 EMAIL_HOST = 'smtp.qq.com'
198 EMAIL_PORT = 25 197 EMAIL_PORT = 25
199 EMAIL_HOST_USER= '*********' 198 EMAIL_HOST_USER= '*********'
200 EMAIL_HOST_PASSWORD= '******' 199 EMAIL_HOST_PASSWORD= '******'
201 DEFAULT_FROM_EMAIL = '*********@qq.com' 200 DEFAULT_FROM_EMAIL = '*********@qq.com'
202 201
203 # 注册用户保留关键字,非Django设置 202 # 注册用户保留关键字,非Django设置
204 RESERVED = ["user", "topic", "home", "setting", "forgot", "login", "logout", "register", "admin"] 203 RESERVED = ["user", "topic", "home", "setting", "forgot", "login", "logout", "register", "admin"]
205 204