##// END OF EJS Templates
Added linked tags feature. If a tag is linked to some tag, it will be added to the thread along with the specified tag.
neko259 -
r279:ac3d84ed default
parent child Browse files
Show More
@@ -0,0 +1,73 b''
1 # -*- coding: utf-8 -*-
2 import datetime
3 from south.db import db
4 from south.v2 import SchemaMigration
5 from django.db import models
6
7
8 class Migration(SchemaMigration):
9
10 def forwards(self, orm):
11 # Adding field 'Tag.linked'
12 db.add_column(u'boards_tag', 'linked',
13 self.gf('django.db.models.fields.related.ForeignKey')(to=orm['boards.Tag'], null=True, blank=True),
14 keep_default=False)
15
16
17 def backwards(self, orm):
18 # Deleting field 'Tag.linked'
19 db.delete_column(u'boards_tag', 'linked_id')
20
21
22 models = {
23 u'boards.ban': {
24 'Meta': {'object_name': 'Ban'},
25 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
26 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'})
27 },
28 u'boards.post': {
29 'Meta': {'object_name': 'Post'},
30 '_text_rendered': ('django.db.models.fields.TextField', [], {}),
31 'bump_time': ('django.db.models.fields.DateTimeField', [], {}),
32 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
33 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}),
34 'image_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
35 'image_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
36 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}),
37 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}),
38 'poster_user_agent': ('django.db.models.fields.TextField', [], {}),
39 'pub_time': ('django.db.models.fields.DateTimeField', [], {}),
40 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'re+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}),
41 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['boards.Tag']", 'symmetrical': 'False'}),
42 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}),
43 'text_markup_type': ('django.db.models.fields.CharField', [], {'default': "'markdown'", 'max_length': '30'}),
44 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['boards.Post']", 'null': 'True'}),
45 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
46 'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['boards.User']", 'null': 'True'})
47 },
48 u'boards.setting': {
49 'Meta': {'object_name': 'Setting'},
50 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
51 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
52 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['boards.User']"}),
53 'value': ('django.db.models.fields.CharField', [], {'max_length': '50'})
54 },
55 u'boards.tag': {
56 'Meta': {'object_name': 'Tag'},
57 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
58 'linked': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['boards.Tag']", 'null': 'True', 'blank': 'True'}),
59 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
60 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tag+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"})
61 },
62 u'boards.user': {
63 'Meta': {'object_name': 'User'},
64 'fav_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['boards.Tag']", 'null': 'True', 'blank': 'True'}),
65 'fav_threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}),
66 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
67 'rank': ('django.db.models.fields.IntegerField', [], {}),
68 'registration_time': ('django.db.models.fields.DateTimeField', [], {}),
69 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '50'})
70 }
71 }
72
73 complete_apps = ['boards'] No newline at end of file
@@ -168,6 +168,7 b' class Tag(models.Model):'
168 name = models.CharField(max_length=100)
168 name = models.CharField(max_length=100)
169 threads = models.ManyToManyField('Post', null=True,
169 threads = models.ManyToManyField('Post', null=True,
170 blank=True, related_name='tag+')
170 blank=True, related_name='tag+')
171 linked = models.ForeignKey('Tag', null=True, blank=True)
171
172
172 def __unicode__(self):
173 def __unicode__(self):
173 return self.name
174 return self.name
@@ -187,6 +188,19 b' class Tag(models.Model):'
187
188
188 return reply_count
189 return reply_count
189
190
191 def get_linked_tags(self):
192 linked_tags = []
193
194 linked_tag = self.linked
195 if linked_tag:
196 linked_tags.append(linked_tag)
197
198 far_tags = linked_tag.get_linked_tags()
199 if len(far_tags) > 0:
200 linked_tags.extend(far_tags)
201
202 return linked_tags
203
190
204
191 class Post(models.Model):
205 class Post(models.Model):
192 """A post is a message."""
206 """A post is a message."""
@@ -22,6 +22,15 b''
22 <a href="{% url 'tag_subscribe' tag.name %}?next={{ request.path }}"
22 <a href="{% url 'tag_subscribe' tag.name %}?next={{ request.path }}"
23 class="not_fav"></a>
23 class="not_fav"></a>
24 {% endif %}
24 {% endif %}
25 {% if tag.linked %}
26 ( +
27 {% for linked_tag in tag.get_linked_tags %}
28 <a class="tag" href="{% url 'tag' linked_tag.name %}">
29 {{ linked_tag.name }}
30 </a>
31 {% endfor %}
32 )
33 {% endif %}
25 <br />
34 <br />
26 {% endfor %}
35 {% endfor %}
27 {% else %}
36 {% else %}
@@ -140,10 +140,10 b' class BoardTests(TestCase):'
140 Tag.objects.all().delete()
140 Tag.objects.all().delete()
141
141
142 tag_name = u'test_tag'
142 tag_name = u'test_tag'
143 tags, = [Tag.objects.get_or_create(name=tag_name)]
143 tag = Tag.objects.create(name=tag_name)
144 client = Client()
144 client = Client()
145
145
146 Post.objects.create_post('title', TEST_TEXT, tags=tags)
146 Post.objects.create_post('title', TEST_TEXT, tags=[tag])
147
147
148 existing_post_id = Post.objects.all()[0].id
148 existing_post_id = Post.objects.all()[0].id
149 response_existing = client.get(THREAD_PAGE + str(existing_post_id) +
149 response_existing = client.get(THREAD_PAGE + str(existing_post_id) +
@@ -174,3 +174,9 b' class BoardTests(TestCase):'
174 self.assertEqual(PAGE_404,
174 self.assertEqual(PAGE_404,
175 response_not_existing.templates[0].name,
175 response_not_existing.templates[0].name,
176 u'Reply is opened as a thread')
176 u'Reply is opened as a thread')
177
178 def test_linked_tag(self):
179 tag = Tag.objects.create(name=u'tag1')
180 linked_tag = Tag.objects.create(name=u'tag2', linked=tag)
181
182 # TODO run add post view and check the tag is added No newline at end of file
@@ -89,6 +89,10 b' def _new_post(request, form, thread_id=b'
89 tag, created = Tag.objects.get_or_create(name=tag_name)
89 tag, created = Tag.objects.get_or_create(name=tag_name)
90 tags.append(tag)
90 tags.append(tag)
91
91
92 linked_tags = tag.get_linked_tags()
93 if len(linked_tags) > 0:
94 tags.extend(linked_tags)
95
92 op = None if thread_id == boards.models.NO_PARENT else \
96 op = None if thread_id == boards.models.NO_PARENT else \
93 get_object_or_404(Post, id=thread_id)
97 get_object_or_404(Post, id=thread_id)
94 post = Post.objects.create_post(title=title, text=text, ip=ip,
98 post = Post.objects.create_post(title=title, text=text, ip=ip,
@@ -85,7 +85,12 b' STATICFILES_FINDERS = ('
85 # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
85 # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
86 )
86 )
87
87
88 STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.CachedStaticFilesStorage'
88 if DEBUG:
89 STATICFILES_STORAGE = \
90 'django.contrib.staticfiles.storage.StaticFilesStorage'
91 else:
92 STATICFILES_STORAGE = \
93 'django.contrib.staticfiles.storage.CachedStaticFilesStorage'
89
94
90 # Make this unique, and don't share it with anybody.
95 # Make this unique, and don't share it with anybody.
91 SECRET_KEY = '@1rc$o(7=tt#kd+4s$u6wchm**z^)4x90)7f6z(i&amp;55@o11*8o'
96 SECRET_KEY = '@1rc$o(7=tt#kd+4s$u6wchm**z^)4x90)7f6z(i&amp;55@o11*8o'
@@ -1,5 +1,5 b''
1 = Features =
1 = Features =
2 [NOT STARTED] Connecting tags to each other
2 [DONE] Connecting tags to each other
3 [NOT STARTED] Tree view (JS)
3 [NOT STARTED] Tree view (JS)
4 [NOT STARTED] Adding tags to images filename
4 [NOT STARTED] Adding tags to images filename
5 [NOT STARTED] Federative network for s2s communication
5 [NOT STARTED] Federative network for s2s communication
General Comments 0
You need to be logged in to leave comments. Login now