diff --git a/boards/migrations/0007_auto.py b/boards/migrations/0007_auto.py new file mode 100644 --- /dev/null +++ b/boards/migrations/0007_auto.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding M2M table for field threads on 'Tag' + m2m_table_name = db.shorten_name(u'boards_tag_threads') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('tag', models.ForeignKey(orm[u'boards.tag'], null=False)), + ('post', models.ForeignKey(orm[u'boards.post'], null=False)) + )) + db.create_unique(m2m_table_name, ['tag_id', 'post_id']) + + + def backwards(self, orm): + # Removing M2M table for field threads on 'Tag' + db.delete_table(db.shorten_name(u'boards_tag_threads')) + + + models = { + u'boards.ban': { + 'Meta': {'object_name': 'Ban'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}) + }, + u'boards.post': { + 'Meta': {'object_name': 'Post'}, + '_text_rendered': ('django.db.models.fields.TextField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}), + 'image_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'image_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), + 'parent': ('django.db.models.fields.BigIntegerField', [], {'default': '-1'}), + 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), + 'poster_user_agent': ('django.db.models.fields.TextField', [], {}), + 'pub_time': ('django.db.models.fields.DateTimeField', [], {}), + 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'re+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['boards.Tag']", 'symmetrical': 'False'}), + 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}), + 'text_markup_type': ('django.db.models.fields.CharField', [], {'default': "'markdown'", 'max_length': '30'}), + 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['boards.Post']", 'null': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['boards.User']", 'null': 'True'}) + }, + u'boards.setting': { + 'Meta': {'object_name': 'Setting'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['boards.User']"}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'boards.tag': { + 'Meta': {'object_name': 'Tag'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tag+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}) + }, + u'boards.user': { + 'Meta': {'object_name': 'User'}, + 'fav_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['boards.Tag']", 'null': 'True', 'blank': 'True'}), + 'fav_threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_access_time': ('django.db.models.fields.DateTimeField', [], {}), + 'rank': ('django.db.models.fields.IntegerField', [], {}), + 'registration_time': ('django.db.models.fields.DateTimeField', [], {}), + 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + } + } + + complete_apps = ['boards'] \ No newline at end of file diff --git a/boards/models.py b/boards/models.py --- a/boards/models.py +++ b/boards/models.py @@ -140,13 +140,8 @@ class PostManager(models.Manager): class TagManager(models.Manager): def get_not_empty_tags(self): - all_tags = self.all().order_by('name') - tags = [] - - # TODO Use query here - for tag in all_tags: - if not tag.is_empty(): - tags.append(tag) + tags = self.annotate(Count('threads')) \ + .filter(threads__count__gt=0).order_by('name') return tags @@ -160,6 +155,8 @@ class Tag(models.Model): objects = TagManager() name = models.CharField(max_length=100) + threads = models.ManyToManyField('Post', null=True, + blank=True, related_name='tag+') def __unicode__(self): return self.name @@ -168,8 +165,7 @@ class Tag(models.Model): return self.get_post_count() == 0 def get_post_count(self): - posts_with_tag = Post.objects.get_threads(tag=self) - return posts_with_tag.count() + return self.threads.count() def get_popularity(self): posts_with_tag = Post.objects.get_threads(tag=self) @@ -303,7 +299,10 @@ class User(models.Model): return RANK_MODERATOR >= self.rank def get_sorted_fav_tags(self): - return self.fav_tags.order_by('name') + tags = self.fav_tags.annotate(Count('threads'))\ + .filter(threads__count__gt=0).order_by('name') + + return tags def __unicode__(self): return self.user_id + '(' + str(self.rank) + ')' diff --git a/boards/templates/boards/base.html b/boards/templates/boards/base.html --- a/boards/templates/boards/base.html +++ b/boards/templates/boards/base.html @@ -28,10 +28,8 @@