Cloudcmsfaq services as primary category
authorKostas Papadimitriou <kpap@grnet.gr>
Tue, 10 Jul 2012 07:47:34 +0000 (10:47 +0300)
committerKostas Papadimitriou <kpap@grnet.gr>
Tue, 10 Jul 2012 07:48:45 +0000 (10:48 +0300)
Use cloudcmsfaq service model as the primary category of a question

cloudcms/migrate/cloudcmsfaq/0005_auto__add_field_question_service.py [new file with mode: 0644]
cloudcmsfaq/admin.py
cloudcmsfaq/models.py
cloudcmsfaq/templates/cloudcmsfaq/archive.html
cloudcmsfaq/urls.py
cloudcmsfaq/views.py

diff --git a/cloudcms/migrate/cloudcmsfaq/0005_auto__add_field_question_service.py b/cloudcms/migrate/cloudcmsfaq/0005_auto__add_field_question_service.py
new file mode 100644 (file)
index 0000000..b670546
--- /dev/null
@@ -0,0 +1,181 @@
+# -*- 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.service'
+        db.add_column('cloudcmsfaq_question', 'service',
+                      self.gf('django.db.models.fields.related.ForeignKey')(related_name='faqs', null=True, to=orm['cloudcms.Service']),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Question.service'
+        db.delete_column('cloudcmsfaq_question', 'service_id')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        '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': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'cloudcms.application': {
+            'Meta': {'object_name': 'Application'},
+            'app_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'code': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'extra_styles': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+            'facebook_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'favicon': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_favicon'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}),
+            'footer_bottom': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+            'footer_top': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'index_url': ('django.db.models.fields.CharField', [], {'default': "'/'", 'max_length': '255'}),
+            'linked_in_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'logo': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}),
+            'show_twitter_feed_on_top': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'twitter_username': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
+        },
+        'cloudcms.service': {
+            'Meta': {'ordering': "['-ordering']", 'object_name': 'Service'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'})
+        },
+        'cloudcmsfaq.category': {
+            'Meta': {'ordering': "['-ordering']", 'object_name': 'Category'},
+            'display_on_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'})
+        },
+        'cloudcmsfaq.categorytranslation': {
+            'Meta': {'ordering': "['title']", 'object_name': 'CategoryTranslation'},
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsfaq.Category']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'cloudcmsfaq.imagecontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'ImageContent', 'db_table': "'cloudcmsfaq_question_imagecontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'imagecontent_set'", 'to': "orm['cloudcmsfaq.Question']"}),
+            'position': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '10'}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'cloudcmsfaq.question': {
+            'Meta': {'ordering': "['-published_on']", 'object_name': 'Question'},
+            'application': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'faqs'", 'symmetrical': 'False', 'to': "orm['cloudcms.Application']"}),
+            'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'faqs'", 'to': "orm['auth.User']"}),
+            'category': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'faqs'", 'to': "orm['cloudcmsfaq.Category']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_featured': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'language': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'last_changed': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'published_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}),
+            'service': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'faqs'", 'null': 'True', 'to': "orm['cloudcms.Service']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'cloudcmsfaq.rawcontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'RawContent', 'db_table': "'cloudcmsfaq_question_rawcontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rawcontent_set'", 'to': "orm['cloudcmsfaq.Question']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
+        },
+        'cloudcmsfaq.richtextcontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'RichTextContent', 'db_table': "'cloudcmsfaq_question_richtextcontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'richtextcontent_set'", 'to': "orm['cloudcmsfaq.Question']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
+        },
+        'cloudcmsfaq.sectioncontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'SectionContent', 'db_table': "'cloudcmsfaq_question_sectioncontent'"},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'mediafile': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'cloudcmsfaq_sectioncontent_set'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sectioncontent_set'", 'to': "orm['cloudcmsfaq.Question']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'richtext': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'default': "'block'", 'max_length': '10'})
+        },
+        'cloudcmsfaq.templatecontent': {
+            'Meta': {'ordering': "['ordering']", 'object_name': 'TemplateContent', 'db_table': "'cloudcmsfaq_question_templatecontent'"},
+            'filename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'templatecontent_set'", 'to': "orm['cloudcmsfaq.Question']"}),
+            'region': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        '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'}),
+            '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'})
+        },
+        'medialibrary.category': {
+            'Meta': {'ordering': "['parent__title', 'title']", 'object_name': 'Category'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'})
+        },
+        'medialibrary.mediafile': {
+            'Meta': {'object_name': 'MediaFile'},
+            'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}),
+            'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
+            'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '12'})
+        },
+        'sites.site': {
+            'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
+            'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['cloudcmsfaq']
\ No newline at end of file
index d5b18a6..a37ea15 100644 (file)
@@ -44,9 +44,9 @@ CategoryTranslationInline = admin_translationinline(CategoryTranslation,
 
 class QuestionAdmin(item_editor.ItemEditor):
     date_hierarchy = 'published_on'
-    list_display = ['title', 'is_active', 'published_on', 'author']
-    list_editable = ['is_active',]
-    list_filter = ['is_active', 'is_featured', 'category', 'author']
+    list_display = ['title', 'is_active', 'published_on', 'author', 'service', 'category']
+    list_editable = ['is_active', 'service', 'category']
+    list_filter = ['is_active', 'is_featured', 'service', 'category', 'author']
     search_fields = ['title', 'slug']
     prepopulated_fields = {
         'slug': ('title',),
@@ -59,6 +59,7 @@ class QuestionAdmin(item_editor.ItemEditor):
                 ('title', 'slug'),
                 'author',
                 'application',
+                'service',
                 'category',
             ]
         }],
index 7f47d36..175cddb 100644 (file)
@@ -95,11 +95,6 @@ class CategoryTranslation(translations.Translation(Category)):
     def __unicode__(self):
         return self.title
 
-    def get_absolute_url(self):
-        return reverse('cloudcmsfaq_category_archive', 'cloudcmsfaq.urls', (), {
-            'category': self.slug,
-        })
-
     def save(self, *args, **kwargs):
         if not self.slug:
             self.slug = slugify(self.title)
@@ -142,6 +137,9 @@ class Question(Base):
         help_text=_('Will be filled in automatically when question gets published.'))
     last_changed = models.DateTimeField(_('last change'), auto_now=True, editable=False)
 
+    service = models.ForeignKey('cloudcms.Service', verbose_name=_('service'),
+        related_name='faqs', null=True, blank=False)
+
     category = models.ForeignKey(Category, verbose_name=_('category'),
         related_name='faqs', null=False, blank=False)
 
@@ -149,7 +147,7 @@ class Question(Base):
 
     class Meta:
         get_latest_by = 'published_on'
-        ordering = ['-published_on']
+        ordering = ['service', 'category', '-published_on']
         verbose_name = _('faq')
         verbose_name_plural = _('faqs')
 
@@ -160,7 +158,7 @@ class Question(Base):
         try:
             r = reverse('cloudcmsfaq_question_detail', 'cloudcmsfaq.urls', (),
                     {
-                     'category': self.category.translation.slug,
+                     'service': self.service.translation.slug,
                      'slug': self.slug,
                     })
         except Exception, e:
@@ -183,7 +181,7 @@ class Question(Base):
 
 
 # Feincms navigation extension
-class FaqCategoriesNavigationExtension(NavigationExtension):
+class FaqServicesNavigationExtension(NavigationExtension):
     """
     Navigation extension for FeinCMS which lists all categories that user
     wants to include in global site navigation.
@@ -192,10 +190,12 @@ class FaqCategoriesNavigationExtension(NavigationExtension):
     name = _('faq categories')
 
     def children(self, page, **kwargs):
-        for category in Category.objects.filter(display_on_menu=True):
-            url='%scategory/%s/' % (page.get_absolute_url(), category.translation.slug)
+        from cloudcms.models import Service
+
+        for service in Service.objects.filter(display_on_menu=True):
+            url='%sservice/%s/' % (page.get_absolute_url(), service.translation.slug)
             yield PagePretender(
-                title=category.translation.title,
+                title=service.translation.title,
                 tree_id=page.tree_id,
                 url=url,
                 lft=0,
index 9230a9f..c8e3a44 100644 (file)
@@ -1,15 +1,23 @@
-{% load applicationcontent_tags pagination_tags i18n %}
+{% load applicationcontent_tags pagination_tags i18n cloudcms_tags %}
 
 <div class="faq">
-    {% for category in categories %}
+    {% for service in services %}
     <div class="faq-category">
-        <h2>{{ category.translation.title|upper }}</h2>
+        <h2>{{ service.translation.title|upper }}</h2>
         <ul>
-            {% for q in category.faqs.active %}
-            <li {% if q == question %}class="current"{% endif %}>
-                <a href="{{ q.get_absolute_url }}">{{ q.title }}</a>
-            </li>
+            <li class="category">
+            {% for category, questions in service|get_service_faqs %}
+              <h3>{{ category.translation.title|upper }}</h3>
+              <ul>
+                {% for q in questions %}
+                  <li {% if q == question %}class="current"{% endif %}>
+                    <a href="{{ q.get_absolute_url }}">{{ q.title }}</a>
+                  </li>
+                  {% endfor %}
+                  <br />
+              </ul>
             {% endfor %}
+            </li>
         </ul>
     </div>
     {% endfor %}
index c3e28bf..10b66bc 100644 (file)
@@ -40,8 +40,8 @@ admin.autodiscover()
 
 urlpatterns = patterns('cloudcmsfaq.views',
     url(r'^$', 'index', name='cloudcmsfaq_entries_archive'),
-    url(r'^category/(?P<category>\w+)/$', 'archive', name='cloudcmsfaq_category_archive'),
-    url(r'^(?P<category>[-\w]+)/(?P<slug>[-\w]+)/$',
+    url(r'^service/(?P<service>\w+)/$', 'archive', name='cloudcmsfaq_category_archive'),
+    url(r'^(?P<service>[\w]+)-(?P<slug>[-\w]+)/$',
         'detail', name='cloudcmsfaq_question_detail'),
 )
 
index 9c75140..8404454 100644 (file)
@@ -36,7 +36,7 @@ from django.conf import settings
 from django.views.generic.simple import direct_to_template
 from django.http import HttpResponseRedirect, Http404
 
-from cloudcms.models import Application
+from cloudcms.models import Application, Service
 from cloudcmsfaq.models import Question, Category, CategoryTranslation
 
 def index(request):
@@ -47,17 +47,19 @@ def archive(request):
     Display entries list
     """
     app = Application.current()
-    categories = Category.objects.all()
+    services = Service.objects.all()
+
     return direct_to_template(request,
-            "cloudcmsfaq/archive.html", {'categories': categories})
+            "cloudcmsfaq/archive.html", {'services': services})
 
-def detail(request, category, slug):
+def detail(request, service, slug):
     """
     Display detailed question.
     """
     entry = Question.objects.get(slug=slug)
-    categories = Category.objects.filter(pk=entry.category.pk)
+    services = Service.objects.filter(pk=entry.service.pk)
+
     return direct_to_template(request,
-            "cloudcmsfaq/detail.html", {'question': entry, 
-                                        'categories': categories})
+            "cloudcmsfaq/detail.html", {'question': entry,
+                                        'services': services})