##// END OF EJS Templates
Fixed getting posts for a thread. Implemented thread getting test.
neko259 -
r17:e40b2431 default
parent child Browse files
Show More
@@ -1,91 +1,94 b''
1 1 from django.db import models
2 2 from django.http import Http404
3 3 from django.utils import timezone
4 4
5 5 NO_PARENT = -1
6 6 NO_IP = '0.0.0.0'
7 7 UNKNOWN_UA = ''
8 8 DIR_IMAGES = 'images'
9 9
10 10 class PostManager(models.Manager):
11 11
12 12 def create_post(self, title, text, image = None, parent_id = NO_PARENT,
13 13 ip = NO_IP):
14 14 post = self.create(title = title,
15 15 text = text,
16 16 pub_time = timezone.now(),
17 17 parent = parent_id,
18 18 image = image,
19 19 poster_ip = ip,
20 20 poster_user_agent = UNKNOWN_UA)
21 21
22 22 return post
23 23
24 24 def delete_post(self, post):
25 25 children = self.filter(parent = post.id)
26 26 for child in children:
27 27 self.delete_post(child)
28 28 post.delete()
29 29
30 30 def delete_posts_by_ip(self, ip):
31 31 posts = self.filter(poster_ip = ip)
32 32 for post in posts:
33 33 self.delete_post(post)
34 34
35 35 def get_threads(self, tag = None):
36 36 if tag is None:
37 37 threads = self.filter(parent = NO_PARENT)
38 38 else:
39 39 threads = self.filter(parent = NO_PARENT, tag = tag)
40 40
41 41 return threads
42 42
43 43 def get_thread(self, opening_post_id):
44 opening_post = self.get(opening_post_id)
44 opening_post = self.get(id = opening_post_id)
45 45 replies = self.filter(parent = opening_post_id)
46 46
47 return [opening_post, replies]
47 thread = [opening_post]
48 thread.extend(replies)
49
50 return thread
48 51
49 52 def exists(self, post_id):
50 53 posts = self.filter(id = post_id)
51 54
52 55 return len(posts) > 0
53 56
54 57
55 58 class Tag(models.Model):
56 59 """
57 60 A tag is a text node assigned to the post. The tag serves as a board
58 61 section. There can be multiple tags for each message
59 62 """
60 63
61 64 name = models.CharField(max_length = 100)
62 65
63 66
64 67 class Post(models.Model):
65 68 """A post is a message."""
66 69
67 70 objects = PostManager()
68 71
69 72 title = models.CharField(max_length = 100)
70 73 pub_time = models.DateTimeField()
71 74 text = models.TextField()
72 75 image = models.ImageField(upload_to = DIR_IMAGES, blank = True)
73 76 poster_ip = models.IPAddressField()
74 77 poster_user_agent = models.TextField()
75 78 parent = models.BigIntegerField()
76 79 tags = models.ManyToManyField(Tag)
77 80
78 81 def __unicode__(self):
79 82 return self.title + ' (' + self.text + ')'
80 83
81 84
82 85 class Admin(models.Model):
83 86 """
84 87 Model for admin users
85 88 """
86 89 name = models.CharField(max_length = 100)
87 90 password = models.CharField(max_length = 100)
88 91
89 92 def __unicode__(self):
90 93 return self.name + '/' + '*' * len(self.password)
91 94
@@ -1,88 +1,99 b''
1 1 from django.utils.unittest import TestCase
2 2 from django.test.client import Client
3 3
4 4 import boards
5 5
6 6 from boards.models import Post, Admin
7 7
8 8
9 9 class BoardTests(TestCase):
10 10
11 11 def _create_post(self):
12 12 return Post.objects.create_post(title = 'title',
13 13 text = 'text')
14 14
15 15 def test_post_add(self):
16 16 post = self._create_post()
17 17
18 18 self.assertIsNotNone(post)
19 19 self.assertEqual(boards.models.NO_PARENT, post.parent)
20 20
21 21 def test_delete_post(self):
22 22 post = self._create_post()
23 23 post_id = post.id
24 24
25 25 Post.objects.delete_post(post)
26 26
27 27 self.assertFalse(Post.objects.exists(post_id))
28 28
29 29 def test_delete_posts_by_ip(self):
30 30 post = self._create_post()
31 31 post_id = post.id
32 32
33 33 Post.objects.delete_posts_by_ip('0.0.0.0')
34 34
35 35 self.assertFalse(Post.objects.exists(post_id))
36 36
37 37 # Authentication tests
38 38
39 39 def _create_test_user(self):
40 40 admin = Admin(name = 'test_username12313584353165',
41 41 password = 'test_userpassword135135512')
42 42
43 43 admin.save()
44 44 return admin
45 45
46 46 def test_admin_login(self):
47 47 client = Client()
48 48
49 49 self.assertFalse('admin' in client.session)
50 50
51 51 admin = self._create_test_user()
52 52
53 53 response = client.post('/boards/login',
54 54 {'name': admin.name, 'password': admin.password})
55 55
56 56 # it means that login passed and user are redirected to another page
57 57 self.assertEqual(302, response.status_code)
58 58
59 59 self.assertTrue('admin' in client.session)
60 60 self.assertTrue(client.session['admin'])
61 61
62 62 admin.delete()
63 63
64 64 wrong_name = 'sd2f1s3d21fs3d21f'
65 65 wrong_password = 'sd2f1s3d21fs3d21fsdfsd'
66 66
67 67 client.post('/boards/login', {'name': wrong_name, 'password': wrong_password})
68 68 self.assertFalse(client.session['admin'])
69 69
70 70 def test_admin_logout(self):
71 71 client = Client()
72 72
73 73
74 74 self.assertFalse('admin' in client.session)
75 75
76 76 admin = self._create_test_user()
77 77
78 78 client.post('/boards/login',
79 79 {'name': admin.name, 'password': admin.password})
80 80
81 81 self.assertTrue(client.session['admin'])
82 82
83 83 client.get('/boards/logout')
84 84
85 85 self.assertFalse(client.session['admin'])
86 86
87 87 admin.delete()
88 88
89 def test_get_thread(self):
90 opening_post = self._create_post()
91 op_id = opening_post.id
92
93 for i in range(0, 2):
94 Post.objects.create_post('title', 'text',
95 parent_id = op_id)
96
97 thread = Post.objects.get_thread(op_id)
98
99 self.assertEqual(3, thread.__len__())
@@ -1,21 +1,21 b''
1 1 from django.conf.urls import patterns, url
2 2 from boards import views
3 3
4 4 urlpatterns = patterns('',
5 5
6 6 # /boards/
7 7 url(r'^$', views.index, name = 'index'),
8 8
9 9 # login page
10 10 url(r'^login$', views.login, name='login'),
11 11 # logout page
12 12 url(r'^logout$', views.logout, name='logout'),
13 13
14 14 # /boards/tag/
15 url(r'^(?P<tag>\w+)/$', views.tag, name = 'tag'),
15 url(r'^tag/(?P<tag>\w+)/$', views.tag, name = 'tag'),
16 16 # /boards/post_id/
17 url(r'^(?P<post>\w+)/$', views.thread, name = 'thread'),
17 url(r'^post/(?P<id>\w+)/$', views.thread, name = 'thread'),
18 18 # /boards/tag/post/
19 19 url(r'^post.html$', views.new_post,
20 20 name='post'),
21 21 )
@@ -1,86 +1,85 b''
1 1 from django.template import RequestContext
2 2 from boards import forms
3 3 from boards.models import Post, Admin
4 4 from django.shortcuts import render, get_list_or_404
5 5 from django.http import HttpResponseRedirect, Http404
6 6
7 7 def index(request):
8 8 context = RequestContext(request)
9 9
10 10 if request.method == 'POST':
11 11 Post.objects.create_post(request.POST['title'],
12 12 request.POST['text'], ip = request.META['REMOTE_ADDR'])
13 13
14 14 threads = Post.objects.get_threads()
15 15
16 16 context['threads'] = None if len(threads) == 0 else threads
17 17 context['form'] = forms.NewThreadForm()
18 18
19 19 return render(request, 'posting_general.html',
20 20 context)
21 21
22 22 def new_post(request):
23 23 """Add a new post (in thread or as a reply)."""
24 24
25 25 title = request.POST['title']
26 26 text = request.POST['text']
27 27
28 28 image = request.POST['image']
29 29
30 30 # TODO Get tags list, download image (if link is given)
31 31
32 32 post = Post.objects.create_post(title = title, text = text, image = image)
33 33
34 34 # TODO Show the thread with a newly created post
35 35
36 36 def tag(request):
37 37 """Get all tag threads (posts without a parent)."""
38 38
39 39 tag_name = request.GET['tag']
40 40
41 41 threads = get_list_or_404(Post, tag = tag_name)
42 42
43 43 context = RequestContext(request)
44 44 context['threads'] = None if len(threads) == 0 else threads
45 45 context['tag'] = tag_name
46 46
47 47 return render(request, 'posting_general.html',
48 48 context)
49 49
50 def thread(request):
50 def thread(request, id):
51 51 """Get all thread posts"""
52 52
53 53 # TODO Show 404 if there is no such thread
54 54
55 opening_post_id = request.GET['id']
56 posts = Post.objects.get_thread(opening_post_id)
55 posts = Post.objects.get_thread(id)
57 56
58 57 context = RequestContext(request)
59 58 context['posts'] = posts
60 59
61 return render(request), 'thread.html'
60 return render(request, 'thread.html', context)
62 61
63 62 def login(request):
64 63 """Log in as admin"""
65 64
66 65 if 'name' in request.POST and 'password' in request.POST:
67 66 request.session['admin'] = False
68 67
69 68 isAdmin = len(Admin.objects.filter(name = request.POST['name'],
70 69 password = request.POST['password'])) > 0
71 70
72 71 if isAdmin :
73 72 request.session['admin'] = True
74 73
75 74 response = HttpResponseRedirect('/boards')
76 75
77 76 else:
78 77 response = render(request, 'login.html', {'error' : 'Login error'})
79 78 else:
80 79 response = render(request, 'login.html', {})
81 80
82 81 return response
83 82
84 83 def logout(request):
85 84 request.session['admin'] = False
86 85 return HttpResponseRedirect('/boards')
@@ -1,27 +1,28 b''
1 1 {% extends "base.html" %}
2 2
3 3 {% block content %}
4 4
5 5 {% if threads %}
6 6 {% for thread in threads %}
7 7 <span class="title">{{ thread.title }}</span><br />
8 8 <span class="text">{{ thread.text }}</span><br />
9 <a class="link" href="/boards/id/{{ thread.id }}/">View thread</a>
9 <a class="link" href="/boards/post/{{ thread.id }}/">View
10 thread</a>
10 11 <hr />
11 12 {% endfor %}
12 13 {% else %}
13 14 No threads found.
14 15 <hr />
15 16 {% endif %}
16 17
17 18 <div class="post-form">
18 19 <form action="/boards/" method="post">{% csrf_token %}
19 20 {{ form.as_p }}
20 21 <input type="submit" value="Post!" />
21 22 </form>
22 23 </div>
23 24
24 25 <HR />
25 26
26 27 {% endblock %}
27 28
General Comments 0
You need to be logged in to leave comments. Login now