From 47159c842cfd3d7e05f6e5750cde5b0f4a225939 Mon Sep 17 00:00:00 2001 From: Hugo Caille Date: Wed, 18 Sep 2013 23:26:09 +0200 Subject: [PATCH 1/4] Adding topic list on index page. When a question is marked as topic, it's promoted before the question list and "no answers" message is hidden. --- ..._chg_field_question_user__chg_field_res.py | 111 ++++++++++++++++++ knowledge/models.py | 2 + .../templates/django_knowledge/index.html | 9 ++ .../django_knowledge/topic_list.html | 8 ++ knowledge/views.py | 10 ++ 5 files changed, 140 insertions(+) create mode 100644 knowledge/migrations/0004_auto__add_field_question_topic__chg_field_question_user__chg_field_res.py create mode 100644 knowledge/templates/django_knowledge/topic_list.html diff --git a/knowledge/migrations/0004_auto__add_field_question_topic__chg_field_question_user__chg_field_res.py b/knowledge/migrations/0004_auto__add_field_question_topic__chg_field_question_user__chg_field_res.py new file mode 100644 index 0000000..0d60f9f --- /dev/null +++ b/knowledge/migrations/0004_auto__add_field_question_topic__chg_field_question_user__chg_field_res.py @@ -0,0 +1,111 @@ +# -*- 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 field 'Question.topic' + db.add_column(u'knowledge_question', 'topic', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + + # Changing field 'Question.user' + db.alter_column(u'knowledge_question', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)) + + # Changing field 'Response.user' + db.alter_column(u'knowledge_response', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)) + + def backwards(self, orm): + # Deleting field 'Question.topic' + db.delete_column(u'knowledge_question', 'topic') + + + # Changing field 'Question.user' + db.alter_column(u'knowledge_question', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm[user_model_label], null=True)) + + # Changing field 'Response.user' + db.alter_column(u'knowledge_response', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm[user_model_label], null=True)) + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'knowledge.category': { + 'Meta': {'ordering': "['title']", 'object_name': 'Category'}, + 'added': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'knowledge.question': { + 'Meta': {'ordering': "['-added']", 'object_name': 'Question'}, + 'added': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'alert': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'body': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['knowledge.Category']", 'symmetrical': 'False', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'private'", 'max_length': '32', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'topic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}) + }, + u'knowledge.response': { + 'Meta': {'ordering': "['added']", 'object_name': 'Response'}, + 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'added': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'alert': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'body': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lastchanged': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'responses'", 'to': u"orm['knowledge.Question']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'inherit'", 'max_length': '32', 'db_index': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['knowledge'] \ No newline at end of file diff --git a/knowledge/models.py b/knowledge/models.py index 1e58676..a354200 100644 --- a/knowledge/models.py +++ b/knowledge/models.py @@ -160,6 +160,8 @@ class Question(KnowledgeBase): default='private', db_index=True) locked = models.BooleanField(default=False) + + topic = models.BooleanField(default=False) categories = models.ManyToManyField('knowledge.Category', blank=True) diff --git a/knowledge/templates/django_knowledge/index.html b/knowledge/templates/django_knowledge/index.html index 51e0a30..1ee46fe 100644 --- a/knowledge/templates/django_knowledge/index.html +++ b/knowledge/templates/django_knowledge/index.html @@ -7,6 +7,15 @@ {% block knowledge_widgets %} +{% if has_topics %} +
+

{% trans "Help Topics" %}

+
+ + {% include 'django_knowledge/topic_list.html' %} +
+{% endif %} +

{% blocktrans with count=questions|length %}Top {{ count }} Questions{% endblocktrans %}


diff --git a/knowledge/templates/django_knowledge/topic_list.html b/knowledge/templates/django_knowledge/topic_list.html new file mode 100644 index 0000000..dc44737 --- /dev/null +++ b/knowledge/templates/django_knowledge/topic_list.html @@ -0,0 +1,8 @@ +{% load i18n %} +{% load url from future %} + +
    + {% for question in topics %} +
  1. {{ question.title }}  {% if not question.get_responses and not question.topic %}{% trans "no responses" %}{% else %}{{ question.get_responses|length }} responses{% endif %}  {% if question.accepted %}{% trans "accepted" %} {% endif %} {% if question.user.is_staff %}{% trans "staff" %} {% endif %} by {{ question.get_name }}
  2. + {% endfor %} +
\ No newline at end of file diff --git a/knowledge/views.py b/knowledge/views.py index 5c53316..a9f9cb8 100644 --- a/knowledge/views.py +++ b/knowledge/views.py @@ -46,10 +46,20 @@ def knowledge_index(request, .prefetch_related('responses__question')[0:20] # this is for get_responses() [setattr(q, '_requesting_user', request.user) for q in questions] + + topics = Question.objects.can_view(request.user)\ + .prefetch_related('responses__question').filter(topic=True)\ + .order_by('title')[0:20] + + has_topics = False + if len(topics) > 0: + has_topics = True return render(request, template, { 'request': request, 'questions': questions, + 'has_topics' : has_topics, + 'topics' : topics, 'my_questions': get_my_questions(request), 'categories': Category.objects.all() }) From 8120827a1b0e4ed63566372ad48ee1599dcb0154 Mon Sep 17 00:00:00 2001 From: Hugo Caille Date: Wed, 18 Sep 2013 23:38:53 +0200 Subject: [PATCH 2/4] - Top Questions doesn' show questions marked as topics anymore. - Fixed bad indentation. --- knowledge/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/knowledge/views.py b/knowledge/views.py index a9f9cb8..804776b 100644 --- a/knowledge/views.py +++ b/knowledge/views.py @@ -43,7 +43,7 @@ def knowledge_index(request, return HttpResponseRedirect(settings.LOGIN_URL+"?next=%s" % request.path) questions = Question.objects.can_view(request.user)\ - .prefetch_related('responses__question')[0:20] + .prefetch_related('responses__question').filter(topic=False)[0:20] # this is for get_responses() [setattr(q, '_requesting_user', request.user) for q in questions] From 0798c4bb3e6ac3c96fb75164fcf11727cd31ae9c Mon Sep 17 00:00:00 2001 From: Hugo Caille Date: Thu, 19 Sep 2013 07:23:15 +0200 Subject: [PATCH 3/4] Added set_topic mod in mod bar to allow user set or unset the question as topic. --- knowledge/models.py | 8 +++++++- knowledge/views.py | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/knowledge/models.py b/knowledge/models.py index a354200..25d383b 100644 --- a/knowledge/models.py +++ b/knowledge/models.py @@ -195,6 +195,12 @@ def lock(self, save=True): if save: self.save() lock.alters_data = True + + def set_topic(self, save=True): + self.topic = not self.topic + if save: + self.save() + set_topic.alters_data = True ################### #### RESPONSES #### @@ -243,7 +249,7 @@ def states(self): """ Handy for checking for mod bar button state. """ - return [self.status, 'lock' if self.locked else None] + return [self.status, 'lock' if self.locked else None, 'set_topic' if self.topic else None] @property def url(self): diff --git a/knowledge/views.py b/knowledge/views.py index 804776b..3e2f341 100644 --- a/knowledge/views.py +++ b/knowledge/views.py @@ -14,6 +14,7 @@ 'question': [ 'private', 'public', 'delete', 'lock', + 'set_topic', 'clear_accepted' ], 'response': [ From e4799baf49419463d65fac6c088ec26069f63ca7 Mon Sep 17 00:00:00 2001 From: Hugo Caille Date: Fri, 20 Sep 2013 13:31:10 +0200 Subject: [PATCH 4/4] Removed has_topics variable from index.html template --- knowledge/templates/django_knowledge/index.html | 2 +- knowledge/views.py | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/knowledge/templates/django_knowledge/index.html b/knowledge/templates/django_knowledge/index.html index 1ee46fe..28dfe70 100644 --- a/knowledge/templates/django_knowledge/index.html +++ b/knowledge/templates/django_knowledge/index.html @@ -7,7 +7,7 @@ {% block knowledge_widgets %} -{% if has_topics %} +{% if not topics|length_is:0 %}

{% trans "Help Topics" %}


diff --git a/knowledge/views.py b/knowledge/views.py index 3e2f341..63e151f 100644 --- a/knowledge/views.py +++ b/knowledge/views.py @@ -51,15 +51,10 @@ def knowledge_index(request, topics = Question.objects.can_view(request.user)\ .prefetch_related('responses__question').filter(topic=True)\ .order_by('title')[0:20] - - has_topics = False - if len(topics) > 0: - has_topics = True return render(request, template, { 'request': request, 'questions': questions, - 'has_topics' : has_topics, 'topics' : topics, 'my_questions': get_my_questions(request), 'categories': Category.objects.all()