diff options
-rw-r--r-- | askbot/migrations/0135_auto__add_questionwidget__add_askwidget.py (renamed from askbot/migrations/0135_auto__add_askwidget.py) | 40 | ||||
-rw-r--r-- | askbot/models/widgets.py | 17 | ||||
-rw-r--r-- | askbot/skins/default/templates/embed/question_widget.html | 5 | ||||
-rw-r--r-- | askbot/tests/utils.py | 25 | ||||
-rw-r--r-- | askbot/tests/widget_tests.py | 32 | ||||
-rw-r--r-- | askbot/urls.py | 15 | ||||
-rw-r--r-- | askbot/views/widgets.py | 25 |
7 files changed, 123 insertions, 36 deletions
diff --git a/askbot/migrations/0135_auto__add_askwidget.py b/askbot/migrations/0135_auto__add_questionwidget__add_askwidget.py index 0764e11d..a2e67352 100644 --- a/askbot/migrations/0135_auto__add_askwidget.py +++ b/askbot/migrations/0135_auto__add_questionwidget__add_askwidget.py @@ -8,21 +8,37 @@ class Migration(SchemaMigration): def forwards(self, orm): + # Adding model 'QuestionWidget' + db.create_table('askbot_questionwidget', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('title', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('question_number', self.gf('django.db.models.fields.PositiveIntegerField')(default=7)), + ('tagnames', self.gf('django.db.models.fields.CharField')(max_length=50)), + ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['askbot.Tag'], null=True, blank=True)), + ('search_query', self.gf('django.db.models.fields.CharField')(max_length=50)), + ('order_by', self.gf('django.db.models.fields.CharField')(default='-added_at', max_length=18)), + ('style', self.gf('django.db.models.fields.TextField')(default='', blank=True)), + )) + db.send_create_signal('askbot', ['QuestionWidget']) + # Adding model 'AskWidget' db.create_table('askbot_askwidget', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('title', self.gf('django.db.models.fields.CharField')(max_length=100)), ('group', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='groups', null=True, to=orm['askbot.Tag'])), ('tag', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['askbot.Tag'], null=True, blank=True)), - ('include_text_field', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)), - ('inner_style', self.gf('django.db.models.fields.TextField')(default='')), - ('outer_style', self.gf('django.db.models.fields.TextField')(default='')), + ('include_text_field', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('inner_style', self.gf('django.db.models.fields.TextField')(default='', blank=True)), + ('outer_style', self.gf('django.db.models.fields.TextField')(default='', blank=True)), )) db.send_create_signal('askbot', ['AskWidget']) def backwards(self, orm): + # Deleting model 'QuestionWidget' + db.delete_table('askbot_questionwidget') + # Deleting model 'AskWidget' db.delete_table('askbot_askwidget') @@ -77,11 +93,12 @@ class Migration(SchemaMigration): }, 'askbot.askwidget': { 'Meta': {'object_name': 'AskWidget'}, - 'tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Tag']", 'null': 'True', 'blank': 'True'}), 'group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'groups'", 'null': 'True', 'to': "orm['askbot.Tag']"}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'inner_style': ('django.db.models.fields.TextField', [], {'default': "''"}), - 'outer_style': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'include_text_field': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'inner_style': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'outer_style': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Tag']", 'null': 'True', 'blank': 'True'}), 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) }, 'askbot.award': { @@ -227,6 +244,17 @@ class Migration(SchemaMigration): 'when': ('django.db.models.fields.DateTimeField', [], {}), 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"}) }, + 'askbot.questionwidget': { + 'Meta': {'object_name': 'QuestionWidget'}, + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Tag']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order_by': ('django.db.models.fields.CharField', [], {'default': "'-added_at'", 'max_length': '18'}), + 'question_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '7'}), + 'search_query': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'style': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, 'askbot.replyaddress': { 'Meta': {'object_name': 'ReplyAddress'}, 'address': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}), diff --git a/askbot/models/widgets.py b/askbot/models/widgets.py index 473a2b73..928cb76e 100644 --- a/askbot/models/widgets.py +++ b/askbot/models/widgets.py @@ -30,13 +30,26 @@ class AskWidget(models.Model): def __unicode__(self): return "Widget: %s" % self.title +SEARCH_ORDER_BY = ( + ('-added_at', _('date ascendant')), + ('added_at', _('date descendant')), + ('-last_activity_at', _('activity descendant')), + ('last_activity_at', _('activity ascendant')), + ('-answer_count', _('answers descendant')), + ('answer_count', _('answers ascendant')), + ('-score', _('votes descendant')), + ('score', _('votes ascendant')), + ) + class QuestionWidget(models.Model): title = models.CharField(max_length=100) question_number = models.PositiveIntegerField(default=7) - tagnames = models.CharField('tags', max_length=50) + tagnames = models.CharField(_('tags'), max_length=50) group = models.ForeignKey(Tag, null=True, blank=True) search_query = models.CharField(max_length=50) - style = models.TextField('css for the widget', + order_by = models.CharField(max_length=18, + choices=SEARCH_ORDER_BY, default='-added_at') + style = models.TextField(_('css for the widget'), default=DEFAULT_INNER_STYLE, blank=True) class Meta: diff --git a/askbot/skins/default/templates/embed/question_widget.html b/askbot/skins/default/templates/embed/question_widget.html index 9d32294b..6857b4a2 100644 --- a/askbot/skins/default/templates/embed/question_widget.html +++ b/askbot/skins/default/templates/embed/question_widget.html @@ -3,11 +3,11 @@ <html> <head> <style type="text/css"> - {{settings.QUESTIONS_WIDGET_CSS|safe}} + {{widget.style|safe}} </style> </head> <body> - {{settings.QUESTIONS_WIDGET_HEADER|safe}} + {{widget.title|safe}} <div id="container"> <ul> {% for thread in threads %} @@ -16,6 +16,5 @@ {% endfor %} </ul> </div> - {{settings.QUESTIONS_WIDGET_FOOTER|safe}} </body> </html> diff --git a/askbot/tests/utils.py b/askbot/tests/utils.py index dd46e31d..99f43677 100644 --- a/askbot/tests/utils.py +++ b/askbot/tests/utils.py @@ -5,8 +5,8 @@ from functools import wraps from askbot import models def create_user( - username = None, - email = None, + username = None, + email = None, notification_schedule = None, date_joined = None, status = 'a', @@ -25,13 +25,13 @@ def create_user( * 'q_sel' - questions that user decides to follow * 'm_and_c' - comments and mentions of user anywhere - and values as keys in + and values as keys in :attr:`~askbot.models.EmailFeedSetting.FEED_TYPES`: * 'i' - instantly * 'd' - daily * 'w' - weekly - * 'n' - never + * 'n' - never """ user = models.User.objects.create_user(username, email) @@ -42,7 +42,7 @@ def create_user( user.set_status(status) if notification_schedule == None: notification_schedule = models.EmailFeedSetting.NO_EMAIL_SCHEDULE - + #a hack, we need to delete these, that will be created automatically #because just below we will be replacing them with the new values user.notification_subscriptions.all().delete() @@ -107,9 +107,16 @@ class AskbotTestCase(TestCase): args_list.pop(1)#so we can remove an item self.assertRaises(*args_list, **kwargs) + def assertQuerysetEqual(self, qs1, qs2, transform=repr, ordered=True): + '''borrowed from django1.4 and modified a bit''' + items = map(transform, qs1) + values = map(transform, qs2) + if not ordered: + return self.assertEqual(set(items), set(values)) + return self.assertEqual(list(items), list(values)) def post_question( - self, + self, user = None, title = 'test question title', body_text = 'test question body text', @@ -207,7 +214,7 @@ class AskbotTestCase(TestCase): """reloads model object from the database """ return obj.__class__.objects.get(id = obj.id) - + def post_answer( self, user = None, @@ -258,8 +265,8 @@ class AskbotTestCase(TestCase): by_email = False, timestamp = None ): - """posts and returns a comment to parent post, uses - now timestamp if not given, dummy body_text + """posts and returns a comment to parent post, uses + now timestamp if not given, dummy body_text author is required """ if user is None: diff --git a/askbot/tests/widget_tests.py b/askbot/tests/widget_tests.py index dbb6d635..d8aabfa5 100644 --- a/askbot/tests/widget_tests.py +++ b/askbot/tests/widget_tests.py @@ -129,3 +129,35 @@ class WidgetCreatorViewsTests(AskbotTestCase): # self.client.login(username='user1', password='testpass') # response = self.client.get('/widgets/foo/create/') # self.assertEquals(404, response.status_code) + + +class QuestionWidgetViewsTests(AskbotTestCase): + + def setUp(self): + self.user = self.create_user('testuser') + self.client = Client() + self.widget = models.QuestionWidget.objects.create(title="foo", + question_number=5, search_query='test', + tagnames='test') + + #we post 6 questions! + titles = ('test question 1', 'this is a test', + 'without the magic word', 'test test test', + 'test just another test', 'no magic word', + 'test another', 'I can no believe is a test') + + tagnames = 'test foo bar' + for title in titles: + self.post_question(title=title, tags=tagnames) + + def test_valid_response(self): + filter_params = {'title__icontains': self.widget.search_query, + 'tags__name__in': self.widget.tagnames.split(' ')} + + threads = models.Thread.objects.filter(**filter_params)[:5] + + response = self.client.get(reverse('question_widget', args=(self.widget.id, ))) + self.assertEquals(200, response.status_code) + + self.assertQuerysetEqual(threads, response.context['threads']) + self.assertEquals(self.widget, response.context['widget']) diff --git a/askbot/urls.py b/askbot/urls.py index c55e552e..df3a910a 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -433,16 +433,11 @@ urlpatterns = patterns('', views.widgets.list_widgets, name = 'list_widgets' ), - #url( - # r'^%s%s$' % (_('widgets/'), _('questions/')), - # views.widgets.widget_questions, - # name='widget_questions' - #), - #url( - # r'^widgets/questions/(?P<widget_id>\d+)/$', - # views.widgets.question_widget, - # name = 'question_widget' - #), + url( + r'^widgets/questions/(?P<widget_id>\d+)/$', + views.widgets.question_widget, + name = 'question_widget' + ), url( r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', diff --git a/askbot/views/widgets.py b/askbot/views/widgets.py index 8579c7e1..423b01ee 100644 --- a/askbot/views/widgets.py +++ b/askbot/views/widgets.py @@ -221,13 +221,26 @@ def question_widget(request, widget_id): if request.method != 'GET': raise Http404 - tags_input = request.GET.get('tags','').strip() - if len(tags_input) > 0: - tags = [tag.strip() for tag in tags_input.split(',')] - threads = models.Thread.objects.filter(tags__name__in=tags)[:askbot_settings.QUESTIONS_WIDGET_MAX_QUESTIONS] + filter_params = {} + if widget.tagnames: + filter_params['tags__name__in'] = widget.tagnames.split(' ') + + if widget.group: + filter_params['groups'] = widget.group + + #simple title search for now + if widget.search_query: + filter_params['title__icontains'] = widget.search_query + + if filter_params: + threads = models.Thread.objects.filter(**filter_params).order_by(widget.order_by)[:widget.question_number] else: - threads = models.Thread.objects.all()[:askbot_settings.QUESTIONS_WIDGET_MAX_QUESTIONS] + threads = models.Thread.objects.all().order_by(widget.order_by)[:widget.question_number] + + data = { + 'threads': threads, + 'widget': widget + } - data = { 'threads': threads } return render_into_skin('embed/question_widget.html', data, request) |