diff --git a/opentech/apply/categories/__init__.py b/opentech/apply/categories/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/opentech/apply/categories/admin.py b/opentech/apply/categories/admin.py new file mode 100644 index 0000000000000000000000000000000000000000..805d8aeae3a290387b25ebf04f13cba0121c7b9d --- /dev/null +++ b/opentech/apply/categories/admin.py @@ -0,0 +1,9 @@ +from wagtail.contrib.modeladmin.options import ModelAdmin + +from .models import Category + + +class CategoryAdmin(ModelAdmin): + menu_label = 'Category Questions' + menu_icon = 'list-ul' + model = Category diff --git a/opentech/apply/categories/apps.py b/opentech/apply/categories/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..0ab5f86087f87fa5c0115ee5c5a4c1a6efccffea --- /dev/null +++ b/opentech/apply/categories/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CategoriesConfig(AppConfig): + name = 'categories' diff --git a/opentech/apply/categories/blocks.py b/opentech/apply/categories/blocks.py new file mode 100644 index 0000000000000000000000000000000000000000..8aa502e3afbf0593317ea7049e5e8198051d0921 --- /dev/null +++ b/opentech/apply/categories/blocks.py @@ -0,0 +1,63 @@ +from django import forms +from django.utils.functional import cached_property +from django.utils.translation import ugettext_lazy as _ + +from wagtail.wagtailcore.blocks import BooleanBlock, CharBlock, ChooserBlock, TextBlock +from wagtail.wagtailcore.utils import resolve_model_string + +from opentech.apply.stream_forms.blocks import FormFieldBlock + + +class ModelChooserBlock(ChooserBlock): + widget = forms.Select + + def __init__(self, target_model, **kwargs): + self._target_model = target_model + super().__init__(**kwargs) + + @cached_property + def target_model(self): + return resolve_model_string(self._target_model) + + +class CategoryQuestionBlock(FormFieldBlock): + # Overwrite field label and help text so we can defer to the category + # as required + field_label = CharBlock( + label=_('Label'), + required=False, + help_text=_('Leave blank to use the default Category label'), + ) + help_text = TextBlock( + required=False, + label=_('Leave blank to use the default Category help text'), + ) + category = ModelChooserBlock('categories.Category') + multi = BooleanBlock(label='Multi select', required=False) + + def get_field_class(self, struct_value): + if struct_value['multi']: + return forms.MultipleChoiceField + else: + return forms.ChoiceField + + def use_defaults_from_category(self, kwargs, category): + for field in ['field_label', 'help_text']: + if not kwargs[field]: + kwargs[field] = getattr(category, field) + + return kwargs + + def get_field_kwargs(self, struct_value): + kwargs = super().get_field_kwargs(struct_value) + category = struct_value['category'] + kwargs = self.use_defaults_from_category(kwargs, category) + choices = category.options.values_list('id', 'value') + kwargs.update({'choices': choices}) + return kwargs + + def get_widget(self, struct_value): + if struct_value['multi']: + return forms.CheckboxSelectMultiple + else: + return forms.RadioSelect diff --git a/opentech/apply/categories/migrations/0001_initial.py b/opentech/apply/categories/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..fa8ce2994a2d30959bc9dd9c466191f31832f497 --- /dev/null +++ b/opentech/apply/categories/migrations/0001_initial.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.8 on 2018-01-09 17:52 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import modelcluster.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Category', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('help_text', models.CharField(blank=True, max_length=255)), + ], + options={ + 'verbose_name_plural': 'Categories', + }, + ), + migrations.CreateModel( + name='Option', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sort_order', models.IntegerField(blank=True, editable=False, null=True)), + ('value', models.CharField(max_length=255)), + ('category', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='options', to='categories.Category')), + ], + options={ + 'ordering': ['sort_order'], + 'abstract': False, + }, + ), + ] diff --git a/opentech/apply/categories/migrations/__init__.py b/opentech/apply/categories/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/opentech/apply/categories/models.py b/opentech/apply/categories/models.py new file mode 100644 index 0000000000000000000000000000000000000000..525cb37f7313e92478acc32fcb8164f84f6ad3c6 --- /dev/null +++ b/opentech/apply/categories/models.py @@ -0,0 +1,38 @@ +from django.db import models +from modelcluster.fields import ParentalKey +from modelcluster.models import ClusterableModel +from wagtail.wagtailadmin.edit_handlers import ( + FieldPanel, + InlinePanel, +) +from wagtail.wagtailcore.models import Orderable + + +class Option(Orderable): + value = models.CharField(max_length=255) + category = ParentalKey('Category', related_name='options') + + +class Category(ClusterableModel): + """Used to manage the global select questions used in most of the application form + Also used in the front end by editors when writing about projects. + + When used in a form: name -> field label and help_text -> help_text + """ + name = models.CharField(max_length=255) + help_text = models.CharField(max_length=255, blank=True) + + @property + def field_label(self): + return self.name + + panels = [ + FieldPanel('name'), + InlinePanel('options', label='Options'), + ] + + def __str__(self): + return self.name + + class Meta: + verbose_name_plural = 'Categories' diff --git a/opentech/apply/categories/tests.py b/opentech/apply/categories/tests.py new file mode 100644 index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6 --- /dev/null +++ b/opentech/apply/categories/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/opentech/apply/categories/views.py b/opentech/apply/categories/views.py new file mode 100644 index 0000000000000000000000000000000000000000..91ea44a218fbd2f408430959283f0419c921093e --- /dev/null +++ b/opentech/apply/categories/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/opentech/apply/funds/admin.py b/opentech/apply/funds/admin.py index 702a83c88ff8d1b8928e1fdae4b19bfa37cdb4da..fe493151f18df7ef9b75179009eb93744298add3 100644 --- a/opentech/apply/funds/admin.py +++ b/opentech/apply/funds/admin.py @@ -1,6 +1,7 @@ from wagtail.contrib.modeladmin.options import ModelAdmin, ModelAdminGroup -from .models import ApplicationForm, Category, FundType +from .models import ApplicationForm, FundType +from opentech.apply.categories.admin import CategoryAdmin class FundAdmin(ModelAdmin): @@ -8,12 +9,6 @@ class FundAdmin(ModelAdmin): menu_icon = 'doc-empty' -class CategoryAdmin(ModelAdmin): - menu_label = 'Category Questions' - menu_icon = 'list-ul' - model = Category - - class ApplicationFormAdmin(ModelAdmin): model = ApplicationForm menu_icon = 'form' diff --git a/opentech/apply/funds/blocks.py b/opentech/apply/funds/blocks.py index 6af71dde5a7900c114aecdf692bef1262fc9a667..06513827f13da391874045d3b3f3e0b8f6dc7815 100644 --- a/opentech/apply/funds/blocks.py +++ b/opentech/apply/funds/blocks.py @@ -1,66 +1,8 @@ -from django import forms -from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ -from wagtail.wagtailcore.blocks import BooleanBlock, CharBlock, ChooserBlock, TextBlock -from wagtail.wagtailcore.utils import resolve_model_string +from opentech.apply.stream_forms.blocks import FormFieldsBlock -from opentech.apply.stream_forms.blocks import FormFieldBlock, FormFieldsBlock - - -class CategoryChooserBlock(ChooserBlock): - widget = forms.Select - - def __init__(self, target_model, **kwargs): - self._target_model = target_model - super().__init__(**kwargs) - - @cached_property - def target_model(self): - return resolve_model_string(self._target_model) - - -class CategoryQuestionBlock(FormFieldBlock): - # Overwrite field label and help text so we can defer to the category - # as required - field_label = CharBlock( - label=_('Label'), - required=False, - help_text=_('Leave blank to use the default Category label'), - ) - help_text = TextBlock( - required=False, - label=_('Leave blank to use the default Category help text'), - ) - category = CategoryChooserBlock('apply.Category') - multi = BooleanBlock(label='Multi select', required=False) - - def get_field_class(self, struct_value): - if struct_value['multi']: - return forms.MultipleChoiceField - else: - return forms.ChoiceField - - def use_defaults_from_category(self, kwargs, category): - for field in ['field_label', 'help_text']: - if not kwargs[field]: - kwargs[field] = getattr(category, field) - - return kwargs - - def get_field_kwargs(self, struct_value): - kwargs = super().get_field_kwargs(struct_value) - category = struct_value['category'] - kwargs = self.use_defaults_from_category(kwargs, category) - choices = category.options.values_list('id', 'value') - kwargs.update({'choices': choices}) - return kwargs - - def get_widget(self, struct_value): - if struct_value['multi']: - return forms.CheckboxSelectMultiple - else: - return forms.RadioSelect +from opentech.apply.categories.blocks import CategoryQuestionBlock class CustomFormFieldsBlock(FormFieldsBlock): diff --git a/opentech/apply/funds/migrations/0003_applicationform_category_fundpageform_option.py b/opentech/apply/funds/migrations/0003_applicationform_category_fundpageform_option.py index c84ece40583e60ba423851831d84d6e5191cb0a2..951b3150db0a7138812d28f3b5708031a34cb8e1 100644 --- a/opentech/apply/funds/migrations/0003_applicationform_category_fundpageform_option.py +++ b/opentech/apply/funds/migrations/0003_applicationform_category_fundpageform_option.py @@ -14,6 +14,7 @@ class Migration(migrations.Migration): dependencies = [ ('funds', '0002_fundpage_workflow'), + ('categories', '0001_initial'), ] operations = [ @@ -22,20 +23,9 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=255)), - ('form_fields', wagtail.wagtailcore.fields.StreamField((('char', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.wagtailcore.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.wagtailcore.blocks.CharBlock(label='Default value', required=False))), group='Fields')), ('text', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.TextBlock(label='Default value', required=False))), group='Fields')), ('number', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.CharBlock(label='Default value', required=False))), group='Fields')), ('checkbox', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('default_value', wagtail.wagtailcore.blocks.BooleanBlock(required=False))), group='Fields')), ('radios', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Choice')))), group='Fields')), ('dropdown', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Choice')))), group='Fields')), ('checkboxes', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('checkboxes', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Checkbox')))), group='Fields')), ('date', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.DateBlock(required=False))), group='Fields')), ('time', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.TimeBlock(required=False))), group='Fields')), ('datetime', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.DateTimeBlock(required=False))), group='Fields')), ('image', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False))), group='Fields')), ('file', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False))), group='Fields')), ('text_markup', wagtail.wagtailcore.blocks.RichTextBlock(group='Other')), ('category', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(help_text='Leave blank to use the default Category label', label='Label', required=False)), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Leave blank to use the default Category help text', required=False)), ('category', opentech.apply.funds.blocks.CategoryChooserBlock('apply.Category')), ('multi', wagtail.wagtailcore.blocks.BooleanBlock(label='Multi select', required=False))), group='Custom'))))) + ('form_fields', wagtail.wagtailcore.fields.StreamField((('char', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('format', wagtail.wagtailcore.blocks.ChoiceBlock(choices=[('email', 'Email'), ('url', 'URL')], label='Format', required=False)), ('default_value', wagtail.wagtailcore.blocks.CharBlock(label='Default value', required=False))), group='Fields')), ('text', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.TextBlock(label='Default value', required=False))), group='Fields')), ('number', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.CharBlock(label='Default value', required=False))), group='Fields')), ('checkbox', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('default_value', wagtail.wagtailcore.blocks.BooleanBlock(required=False))), group='Fields')), ('radios', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Choice')))), group='Fields')), ('dropdown', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('choices', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Choice')))), group='Fields')), ('checkboxes', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('checkboxes', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailcore.blocks.CharBlock(label='Checkbox')))), group='Fields')), ('date', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.DateBlock(required=False))), group='Fields')), ('time', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.TimeBlock(required=False))), group='Fields')), ('datetime', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False)), ('default_value', wagtail.wagtailcore.blocks.DateTimeBlock(required=False))), group='Fields')), ('image', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False))), group='Fields')), ('file', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(label='Label')), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Help text', required=False)), ('required', wagtail.wagtailcore.blocks.BooleanBlock(label='Required', required=False))), group='Fields')), ('text_markup', wagtail.wagtailcore.blocks.RichTextBlock(group='Other')), ('category', wagtail.wagtailcore.blocks.StructBlock((('field_label', wagtail.wagtailcore.blocks.CharBlock(help_text='Leave blank to use the default Category label', label='Label', required=False)), ('help_text', wagtail.wagtailcore.blocks.TextBlock(label='Leave blank to use the default Category help text', required=False)), ('category', opentech.apply.categories.blocks.ModelChooserBlock('categories.Category')), ('multi', wagtail.wagtailcore.blocks.BooleanBlock(label='Multi select', required=False))), group='Custom'))))) ], ), - migrations.CreateModel( - name='Category', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('help_text', models.CharField(max_length=255, blank=True)), - ], - options={ - 'verbose_name_plural': 'Categories', - }, - ), migrations.CreateModel( name='FundForm', fields=[ @@ -49,17 +39,4 @@ class Migration(migrations.Migration): 'abstract': False, }, ), - migrations.CreateModel( - name='Option', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('sort_order', models.IntegerField(blank=True, editable=False, null=True)), - ('value', models.CharField(max_length=255)), - ('category', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='options', to='funds.Category')), - ], - options={ - 'ordering': ['sort_order'], - 'abstract': False, - }, - ), ] diff --git a/opentech/apply/funds/models.py b/opentech/apply/funds/models.py index 3a534c107e8c7d71b5d81be1f9e26d528674364a..6752f5165788346836a0e80d4d03a8d67ded24d7 100644 --- a/opentech/apply/funds/models.py +++ b/opentech/apply/funds/models.py @@ -1,6 +1,5 @@ from django.db import models from modelcluster.fields import ParentalKey -from modelcluster.models import ClusterableModel from wagtail.wagtailadmin.edit_handlers import ( FieldPanel, InlinePanel, @@ -21,6 +20,7 @@ WORKFLOW_CLASS = { DoubleStage.name: DoubleStage, } + class FundType(AbstractStreamForm): parent_page_types = ['apply_home.ApplyHomePage'] subpage_types = [] # type: ignore @@ -67,33 +67,3 @@ class ApplicationForm(models.Model): def __str__(self): return self.name - - -class Option(Orderable): - value = models.CharField(max_length=255) - category = ParentalKey('Category', related_name='options') - - -class Category(ClusterableModel): - """Used to manage the global select questions used in most of the application form - Also used in the front end by editors when writing about projects. - - When used in a form: name -> field label and help_text -> help_text - """ - name = models.CharField(max_length=255) - help_text = models.CharField(max_length=255, blank=True) - - @property - def field_label(self): - return self.name - - panels = [ - FieldPanel('name'), - InlinePanel('options', label='Options'), - ] - - def __str__(self): - return self.name - - class Meta: - verbose_name_plural = 'Categories' diff --git a/opentech/settings/base.py b/opentech/settings/base.py index c44ab56451acefb3c7c5510c2fa5d373bf6d25a0..5aaf1a75957fd821d8260707e8c2c7982ee6919b 100644 --- a/opentech/settings/base.py +++ b/opentech/settings/base.py @@ -14,6 +14,7 @@ BASE_DIR = os.path.dirname(PROJECT_DIR) INSTALLED_APPS = [ 'opentech.images', + 'opentech.apply.categories', 'opentech.apply.funds', 'opentech.apply.home', 'opentech.apply.users',