Skip to content
Snippets Groups Projects
Commit dad3cd9e authored by Todd Dembrey's avatar Todd Dembrey
Browse files

create and move the items in the categories app

parent 0668ac22
No related branches found
No related tags found
No related merge requests found
Showing
with 171 additions and 123 deletions
from wagtail.contrib.modeladmin.options import ModelAdmin
from .models import Category
class CategoryAdmin(ModelAdmin):
menu_label = 'Category Questions'
menu_icon = 'list-ul'
model = Category
from django.apps import AppConfig
class CategoriesConfig(AppConfig):
name = 'categories'
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
# -*- 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,
},
),
]
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'
from django.test import TestCase
# Create your tests here.
from django.shortcuts import render
# Create your views here.
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'
......
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):
......
......@@ -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,
},
),
]
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'
......@@ -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',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment