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

Allow storing of category options on the project

parent a0842c0e
No related branches found
No related tags found
No related merge requests found
# -*- coding: utf-8 -*-
# Generated by Django 1.11.8 on 2018-01-17 22:22
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0003_projectpage_status'),
]
operations = [
migrations.AddField(
model_name='projectpage',
name='categories',
field=models.TextField(default='{}'),
preserve_default=False,
),
]
import json
from django.db import models
from django.conf import settings
from django.core.exceptions import ValidationError
......@@ -16,6 +18,7 @@ from wagtail.wagtailcore.fields import StreamField
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtailsearch import index
from opentech.apply.categories.models import Option
from opentech.public.utils.blocks import StoryBlock
from opentech.public.utils.models import (
BaseFunding,
......@@ -24,6 +27,8 @@ from opentech.public.utils.models import (
RelatedPage,
)
from .widgets import CategoriesWidget
class ProjectContactDetails(models.Model):
project_page = ParentalKey(
......@@ -104,6 +109,8 @@ class ProjectPage(FundingMixin, BasePage):
status = models.CharField(choices=STATUSES, max_length=25, default=STATUSES[0][0])
body = StreamField(StoryBlock())
categories = models.TextField()
search_fields = BasePage.search_fields + [
index.SearchField('introduction'),
index.SearchField('body'),
......@@ -114,10 +121,15 @@ class ProjectPage(FundingMixin, BasePage):
FieldPanel('introduction'),
FieldPanel('status'),
StreamFieldPanel('body'),
FieldPanel('categories', widget=CategoriesWidget),
InlinePanel('contact_details', label="Contact Details"),
InlinePanel('related_pages', label="Related Projects"),
] + FundingMixin.content_panels
def category_options(self):
categories = json.loads(self.categories)
options = [int(id) for options in categories.values() for id in options]
return Option.objects.select_related().filter(id__in=options).order_by('category')
class ProjectIndexPage(BasePage):
subpage_types = ['ProjectPage']
......
......@@ -31,4 +31,17 @@
</div>
{% include "utils/includes/funding.html" %}
{% regroup page.category_options by category as categories %}
{% for category, options in categories %}
<ul>
<li><h3>{{ category.name }}</h3>
<ul>
{% for option in options %}
<li>{{ option.value }}</li>
{% endfor %}
</ul>
</li>
</ul>
{% endfor %}
{% endblock content %}
{% spaceless %}<ul class="multiple">{% for widget in widget.subwidgets %}{% include widget.template_name %}{% endfor %}</ul>{% endspaceless %}
<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %} style="width:50%;">{{ widget.label }}</label><div class="field-content" style="width:50%;"><div class="input">{% include "django/forms/widgets/input.html" %}</div></div>
<li>
<h2>{{ widget.attrs.label_tag }}</h2>
<fieldset>
{% with id=widget.attrs.id %}
<ul{% if id %} id="{{ id }}"{% endif %}class="fields {% if widget.attrs.class %}{{ widget.attrs.class }}{% endif %}">{% for group, options, index in widget.optgroups %}
{% for option in options %}
<li {% if id %} id="{{ id }}_{{ index }}"{% endif %}>
<div class="field checkbox_input boolean_field">
{% include option.template_name with widget=option %}{% endfor %}
</div>
</li>
{% endfor %}
</ul>{% endwith %}
</fieldset>
</li>
import json
from django import forms
from opentech.apply.categories.models import Category
class OptionsWidget(forms.CheckboxSelectMultiple):
template_name = 'projects/widgets/options_widget.html'
option_template_name = 'projects/widgets/options_option.html'
class CategoriesWidget(forms.MultiWidget):
template_name = 'projects/widgets/categories_widget.html'
def __init__(self, *args, **kwargs):
widgets = [
OptionsWidget(
attrs={'id': cat.id, 'label_tag': cat.name},
choices=cat.options.all().values_list('id', 'value'),
)
for cat in Category.objects.all()
]
kwargs['widgets'] = widgets
super().__init__(*args, **kwargs)
def decompress(self, value):
data = json.loads(value)
return [
data.get(str(widget.attrs['id']), list()) for widget in self.widgets
]
def value_from_datadict(self, data, files, name):
data = {
widget.attrs['id']: widget.value_from_datadict(data, files, name + '_%s' % i)
for i, widget in enumerate(self.widgets)
}
return json.dumps(data)
def get_context(self, *args, **kwargs):
context = super().get_context(*args, **kwargs)
# Mutliwidget kills the wrap_label option when it is building the context
context['wrap_label'] = True
return context
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