Add updated front end, updated CaseStudy model and profiles app

This commit is contained in:
Livvy Mackintosh
2017-10-31 14:57:26 +00:00
parent f91b4d2a2a
commit 43d6ec989b
30 changed files with 1065 additions and 77 deletions

View File

@ -1,13 +1,14 @@
from django import forms
from django.urls import reverse
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from crispy_forms.layout import Submit, Layout
from crispy_forms.bootstrap import Tab, TabHolder
from leaflet.forms.widgets import LeafletWidget
from moderation.forms import BaseModeratedObjectForm
from .models import CaseStudy
class BaseCaseStudyForm(forms.ModelForm):
class BaseCaseStudyForm(BaseModeratedObjectForm):
"""Base form class for the CaseStudy model."""
def __init__(self, *args, **kwargs):
super(BaseCaseStudyForm, self).__init__(*args, **kwargs)
@ -52,6 +53,11 @@ class ShortCaseStudyForm(BaseCaseStudyForm):
'synopsis',
'full_description',
'image',
'image_caption',
'image_credit',
'video',
'media_coverage_mainstream',
'media_coverage_independent',
'community_voices'
]
@ -61,6 +67,47 @@ class LongCaseStudyForm(BaseCaseStudyForm):
def __init__(self, *args, **kwargs):
super(LongCaseStudyForm, self).__init__(*args, **kwargs)
self.helper.form_action = reverse('long-form')
self.helper.layout = Layout(
TabHolder(
Tab("First Page",
'entry_name',
'location',
'sector_of_economy',
'positive_or_negative',
'country',
'area_of_land',
'land_ownership',
'land_ownership_details',
'location_context',
'type_of_ecosystem',
'describe_ecosystem',
'affects_indigenous',
'affects_indigenous_detail',
'project_status',
'synopsis',
'full_description',
'image',
'image_caption',
'image_credit',
'video',
'media_coverage_mainstream',
'media_coverage_independent',
'community_voices'),
Tab(
"Second Page",
'generation_technology',
'biomass_detail',
'generation_technology_other',
'total_generation_capacity',
'total_investment',
'technical_or_economic_details',
'power_technology',
'power_technology_other',
'energy_storage_capacity',
)))
class Meta(BaseCaseStudyForm.Meta):
fields = '__all__'
fields = '__all__'

View File

@ -0,0 +1,111 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-11 16:06
from __future__ import unicode_literals
import apps.map.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0009_auto_20171007_1544'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='completion_year',
field=models.IntegerField(blank=True, choices=[(1977, 1977), (1978, 1978), (1979, 1979), (1980, 1980), (1981, 1981), (1982, 1982), (1983, 1983), (1984, 1984), (1985, 1985), (1986, 1986), (1987, 1987), (1988, 1988), (1989, 1989), (1990, 1990), (1991, 1991), (1992, 1992), (1993, 1993), (1994, 1994), (1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025), (2026, 2026), (2027, 2027), (2028, 2028), (2029, 2029), (2030, 2030), (2031, 2031), (2032, 2032), (2033, 2033), (2034, 2034), (2035, 2035), (2036, 2036), (2037, 2037), (2038, 2038), (2039, 2039), (2040, 2040), (2041, 2041), (2042, 2042), (2043, 2043), (2044, 2044), (2045, 2045), (2046, 2046), (2047, 2047), (2048, 2048), (2049, 2049), (2050, 2050), (2051, 2051), (2052, 2052), (2053, 2053), (2054, 2054), (2055, 2055), (2056, 2056), (2057, 2057)], default=None, help_text="Select the year the project was completed. If the project hasn't finished, select the projected completion year.", null=True, verbose_name='Completion year'),
),
migrations.AddField(
model_name='casestudy',
name='direct_comms',
field=models.TextField(default=None, help_text='Add any reports of direct communication between community members and representatives of developers/companies/investors.', max_length=500, null=True, verbose_name='Reports of direct communications'),
),
migrations.AddField(
model_name='casestudy',
name='energy_customers',
field=models.CharField(blank=True, default=None, help_text="List any wholesale energy customers that take energy from the development. E.g. 'national grids' or private energy suppliers.", max_length=120, null=True, verbose_name='Energy consumers'),
),
migrations.AddField(
model_name='casestudy',
name='financial_institutions',
field=models.CharField(blank=True, default=None, help_text='List banks and other financial institutions that have or are considering extending loans or guarantees to the project. Separate with a comma.', max_length=120, null=True, verbose_name='Financial institutions'),
),
migrations.AddField(
model_name='casestudy',
name='image_caption',
field=models.CharField(default=None, max_length=500, null=True, verbose_name='Image caption'),
),
migrations.AddField(
model_name='casestudy',
name='image_credit',
field=models.CharField(default=None, max_length=200, null=True, verbose_name='Image credit(s)'),
),
migrations.AddField(
model_name='casestudy',
name='media_coverage_independent',
field=models.TextField(default=None, help_text='Provide any links to grassroots/independent media coverage.', max_length=500, null=True, verbose_name='Independent grassroots reports'),
),
migrations.AddField(
model_name='casestudy',
name='media_coverage_mainstream',
field=models.TextField(default=None, help_text='Provide any links to mainstream media coverage.', max_length=500, null=True, verbose_name='Links to media reports'),
),
migrations.AddField(
model_name='casestudy',
name='project_owners',
field=models.CharField(blank=True, default=None, help_text='List companies or organisations that own the project and/or facilities. Separate with a comma.', max_length=120, null=True, verbose_name='Project and facility owners'),
),
migrations.AddField(
model_name='casestudy',
name='shareholders',
field=models.CharField(blank=True, default=None, help_text="List shareholders of the project owners you've just listed. Separate with a comma.", max_length=120, null=True, verbose_name='Shareholders of the project owners'),
),
migrations.AddField(
model_name='casestudy',
name='social_media_links',
field=models.TextField(blank=True, default=None, help_text='Add any links to social media accounts directly relating to the project.', max_length=500, null=True, verbose_name='Social media links'),
),
migrations.AddField(
model_name='casestudy',
name='start_year',
field=models.IntegerField(blank=True, choices=[(1977, 1977), (1978, 1978), (1979, 1979), (1980, 1980), (1981, 1981), (1982, 1982), (1983, 1983), (1984, 1984), (1985, 1985), (1986, 1986), (1987, 1987), (1988, 1988), (1989, 1989), (1990, 1990), (1991, 1991), (1992, 1992), (1993, 1993), (1994, 1994), (1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017), (2018, 2018), (2019, 2019), (2020, 2020), (2021, 2021), (2022, 2022), (2023, 2023), (2024, 2024), (2025, 2025), (2026, 2026), (2027, 2027), (2028, 2028), (2029, 2029), (2030, 2030), (2031, 2031), (2032, 2032), (2033, 2033), (2034, 2034), (2035, 2035), (2036, 2036), (2037, 2037), (2038, 2038), (2039, 2039), (2040, 2040), (2041, 2041), (2042, 2042), (2043, 2043), (2044, 2044), (2045, 2045), (2046, 2046), (2047, 2047), (2048, 2048), (2049, 2049), (2050, 2050), (2051, 2051), (2052, 2052), (2053, 2053), (2054, 2054), (2055, 2055), (2056, 2056), (2057, 2057)], default=None, help_text="Select the year the project was started. If the project hasn't begun, select the projected start year.", null=True, verbose_name='Start year'),
),
migrations.AddField(
model_name='casestudy',
name='video_caption',
field=models.CharField(default=None, max_length=500, null=True, verbose_name='Video caption'),
),
migrations.AddField(
model_name='casestudy',
name='video_credit',
field=models.CharField(default=None, max_length=500, null=True, verbose_name='Video credit(s)'),
),
migrations.AlterField(
model_name='casestudy',
name='affects_indigenous',
field=models.BooleanField(help_text='Does the project affect indigenous communities?', verbose_name='Affects indigenous people?'),
),
migrations.AlterField(
model_name='casestudy',
name='community_voices',
field=models.TextField(help_text='Add any direct quotes from members of the community that relate to this project', verbose_name='Community Voices'),
),
migrations.AlterField(
model_name='casestudy',
name='date_created',
field=models.DateTimeField(auto_now_add=True),
),
migrations.AlterField(
model_name='casestudy',
name='land_ownership_details',
field=models.CharField(blank=True, help_text="Please specify details about land ownership if you chose 'other'", max_length=256, null=True, verbose_name='Land ownership details'),
),
migrations.AlterField(
model_name='casestudy',
name='video',
field=models.URLField(help_text='Copy the URL to a related YouTube™ video that relates to the case study.', max_length=43, validators=[apps.map.validators.YoutubeURLValidator()], verbose_name='YouTube Video'),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-12 15:52
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0010_auto_20171011_1606'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='generation_technology',
field=models.CharField(blank=True, choices=[('SSWE', 'Small-scale wind energy (less than 500kW)'), ('LSWE', 'Large-scale wind energy (more than 500kW)'), ('SSPV', 'Small-scale photovoltaic electricity (less than 500kW)'), ('LSPV', 'Large-scale photovoltaic electricity (more than 500kW)'), ('STHE', 'Solar thermal electricity (e.g using parabolic reflectors)'), ('SHYD', 'Small hydroelectric (less than 1MW)'), ('MHYD', 'Medium hydroelectric (between 1-20MW)'), ('LHYD', 'Large hydroelectric (more than 20MW - often not considered renewable)'), ('GEOT', 'Geothermal electricity'), ('BIOG', 'Biogas turbine'), ('OTHB', 'Other biomass (including liquid/solid biofuel)')], default=None, help_text='Select the type of renewable energy generation that most applies to this case study.', max_length=4, null=True, verbose_name='Generation technology'),
),
]

View File

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-12 16:10
from __future__ import unicode_literals
import django.contrib.gis.db.models.fields
from django.db import migrations, models
import django_countries.fields
class Migration(migrations.Migration):
dependencies = [
('map', '0011_casestudy_generation_technology'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='biomass_detail',
field=models.CharField(blank=True, default=None, help_text='If you selected biogas or biomass, please describe the feedstock (where the fuel came from e.g. corn, algae, anaerobic digestion, commercial waste etc)', max_length=200, null=True, verbose_name='Generation technology detail'),
),
migrations.AddField(
model_name='casestudy',
name='generation_technology_other',
field=models.CharField(blank=True, default=None, help_text='If you selected other, please specify the generation technology (e.g. tidal, wave etc)', max_length=200, null=True, verbose_name='Other generation type'),
),
migrations.AddField(
model_name='casestudy',
name='total_generation_capacity',
field=models.IntegerField(blank=True, default=None, help_text='Please enter the total generation capacity of the project in kW', null=True, verbose_name='Total generation capacity (in kW)'),
),
migrations.AlterField(
model_name='casestudy',
name='country',
field=django_countries.fields.CountryField(help_text='Select the country of the project', max_length=2, verbose_name='Country field'),
),
migrations.AlterField(
model_name='casestudy',
name='generation_technology',
field=models.CharField(blank=True, choices=[('SSWE', 'Small-scale wind energy (less than 500kW)'), ('LSWE', 'Large-scale wind energy (more than 500kW)'), ('SSPV', 'Small-scale photovoltaic electricity (less than 500kW)'), ('LSPV', 'Large-scale photovoltaic electricity (more than 500kW)'), ('STHE', 'Solar thermal electricity (e.g using parabolic reflectors)'), ('SHYD', 'Small hydroelectric (less than 1MW)'), ('MHYD', 'Medium hydroelectric (between 1-20MW)'), ('LHYD', 'Large hydroelectric (more than 20MW - often not considered renewable)'), ('GEOT', 'Geothermal electricity'), ('BIOG', 'Biogas turbine'), ('OTHB', 'Other biomass (including liquid/solid biofuel)'), ('OTHR', 'Other (tidal, wave etc)')], default=None, help_text='Select the type of renewable energy generation that most applies to this case study.', max_length=4, null=True, verbose_name='Generation technology'),
),
migrations.AlterField(
model_name='casestudy',
name='location',
field=django.contrib.gis.db.models.fields.PointField(help_text='Place a marker using the tools on the left of the map. Zoom in as far as you can so the placement is accurate (important)', srid=4326, verbose_name='Project location'),
),
]

View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-12 16:40
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0012_auto_20171012_1610'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='technical_or_economic_details',
field=models.CharField(blank=True, default=None, help_text='Specify any additional technical or economic details relating to the project.', max_length=500, null=True, verbose_name='Additional technical or economic details'),
),
migrations.AddField(
model_name='casestudy',
name='total_investment',
field=models.IntegerField(blank=True, default=None, help_text='The approximate total investment for the project in USD.', null=True, verbose_name='Total investment (in USD)'),
),
migrations.AlterField(
model_name='casestudy',
name='generation_technology',
field=models.CharField(blank=True, choices=[('Wind energy', (('SSWE', 'Small-scale (less than 500kW)'), ('LSWE', 'Large-scale (more than 500kW)'))), ('Photovoltaic electricity', (('SSPV', 'Small-scale (less than 500kW)'), ('LSPV', 'Large-scale (more than 500kW)'))), ('Hydroelectric', (('SHYD', 'Small-scale (less than 1MW)'), ('MHYD', 'Medium-scale (between 1-20MW)'), ('LHYD', 'Large-scale (more than 20MW - often not considered renewable)'))), ('STHE', 'Solar thermal electricity (e.g using parabolic reflectors)'), ('GEOT', 'Geothermal electricity'), ('BIOG', 'Biogas turbine'), ('OTHB', 'Other biomass (including liquid/solid biofuel)'), ('OTHR', 'Other (tidal, wave etc)')], default=None, help_text='Select the type of renewable energy generation that most applies to this case study.', max_length=4, null=True, verbose_name='Generation technology'),
),
migrations.AlterField(
model_name='casestudy',
name='total_generation_capacity',
field=models.PositiveIntegerField(blank=True, default=None, help_text='Please enter the total generation capacity of the project in kW', null=True, verbose_name='Total generation capacity (in kW)'),
),
]

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-25 20:35
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0013_auto_20171012_1640'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='power_technology',
field=models.CharField(blank=True, choices=[('PT', 'Power transmission (grid lines, substations etc)'), ('ES', 'Energy storage (pumped storage, compressed air, battery systems etc'), ('OT', 'Others')], default=None, help_text='Select the related energy technology.', max_length=2, null=True, verbose_name='Power technology'),
),
migrations.AddField(
model_name='casestudy',
name='power_technology_other',
field=models.CharField(blank=True, default=None, help_text="If you answered 'others', please specify the power technologies.", max_length=128, null=True, verbose_name='Other power technology'),
),
]

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-30 15:50
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0014_auto_20171025_2035'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='energy_storage_capacity',
field=models.IntegerField(blank=True, default=None, help_text='Enter the total capacity of the energy storage system.', null=True, verbose_name='Energy storage capacity'),
),
migrations.AlterField(
model_name='casestudy',
name='affects_indigenous_detail',
field=models.CharField(blank=True, default=None, help_text='What group of indigenous people does the community belong to?', max_length=256, null=True, verbose_name='Affects Indigenous - Details'),
),
]

View File

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-31 14:42
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0015_auto_20171030_1550'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='definition_of_affected_territories',
field=models.CharField(blank=True, default=None, help_text='In your own words, define the territories that the project will affect.', max_length=512, null=True, verbose_name='Definition of affected territories'),
),
migrations.AddField(
model_name='casestudy',
name='official_project_documents',
field=models.FileField(blank=True, default=None, help_text='Attach any legal or official documents that relate to the project.', null=True, upload_to='', verbose_name='Official project documents'),
),
migrations.AddField(
model_name='casestudy',
name='other_documents',
field=models.FileField(blank=True, default=None, help_text='Attach any other documents that relate to the project.', null=True, upload_to='', verbose_name='Other documents'),
),
migrations.AddField(
model_name='casestudy',
name='shown_on_other_platforms',
field=models.NullBooleanField(default=None, help_text='Tick the box if you would like us to show this case study on other social media platforms', verbose_name='Show on other platforms?'),
),
migrations.AddField(
model_name='casestudy',
name='shown_on_other_platforms_detail',
field=models.CharField(blank=True, help_text='List the social media platforms that you would like us to specifically publish the case study on', max_length=128, null=True, verbose_name='Show on other platforms - Detail'),
),
]

View File

@ -1,9 +1,12 @@
import datetime
from urllib import parse
from django.contrib.gis.db import models
from django.contrib.auth.models import User
from django_extensions.db.fields import AutoSlugField
from django_countries.fields import CountryField
from django.utils.translation import ugettext as _
from django.template.defaultfilters import slugify
from . import validators
class CaseStudy(models.Model):
@ -58,6 +61,38 @@ class CaseStudy(models.Model):
('PROJCD', _('Projected Project')),
)
GENERATION_TECHNOLOGY_CHOICES = (
(_('Wind energy'), (
('SSWE', _('Small-scale (less than 500kW)')),
('LSWE', _('Large-scale (more than 500kW)'))
)),
(_('Photovoltaic electricity'), (
('SSPV', _('Small-scale (less than 500kW)')),
('LSPV', _('Large-scale (more than 500kW)'))
)),
(_('Hydroelectric'), (
('SHYD', _('Small-scale (less than 1MW)')),
('MHYD', _('Medium-scale (between 1-20MW)')),
('LHYD', _('Large-scale (more than 20MW - often not considered renewable)')),
)),
('STHE', _('Solar thermal electricity (e.g using parabolic reflectors)')),
('GEOT', _('Geothermal electricity')),
('BIOG', _('Biogas turbine')),
('OTHB', _('Other biomass (including liquid/solid biofuel)')),
('OTHR', _('Other (tidal, wave etc)'))
)
POWER_TECHNOLOGY_CHOICES = (
('PT', _('Power transmission (grid lines, substations etc)')),
('ES', _('Energy storage (pumped storage, compressed air, battery systems etc')),
('OT', _('Others'))
)
# Dynamically generate a list of choices 40 years prior and after the current year.
YEAR_CHOICES = [(r, r) for r in
range((datetime.datetime.now().year - 40),
(datetime.datetime.now().year + 41))]
##
# Meta Fields
##
@ -72,11 +107,16 @@ class CaseStudy(models.Model):
)
# Date and time of submission
date_created = models.DateTimeField(auto_now=True, null=False)
date_created = models.DateTimeField(auto_now_add=True, null=False)
# Slug derived from entry_name, used in urls for SEO
# TODO: Change this so it's not dynamic. Slugs should never change.
slug = AutoSlugField(populate_from=['entry_name'])
##
# First Screen
##
# 1.1
entry_name = models.CharField(
verbose_name=_("Entry Name"),
@ -86,7 +126,11 @@ class CaseStudy(models.Model):
)
# N/A - Not explicitly listed in spec
location = models.PointField()
location = models.PointField(
verbose_name=_("Project location"),
help_text=_("Place a marker using the tools on the left of the map. Zoom in as far as you can so the placement \
is accurate (important)")
)
# 1.2
sector_of_economy = models.CharField(
@ -106,7 +150,10 @@ class CaseStudy(models.Model):
)
# 1.4
country = CountryField()
country = CountryField(
verbose_name=_("Country field"),
help_text=_("Select the country of the project")
)
# 1.5.1
area_of_land = models.IntegerField(
@ -125,9 +172,10 @@ class CaseStudy(models.Model):
# 1.5.3
land_ownership_details = models.CharField(
verbose_name=_("Land ownership details"),
help_text=_("Add any details and other remarks about the land\
ownership"),
max_length=256
help_text=_("Please specify details about land ownership if you chose 'other'"),
max_length=256,
null=True,
blank=True,
)
# 1.5.4
@ -157,7 +205,7 @@ class CaseStudy(models.Model):
# 1.5.6
affects_indigenous = models.BooleanField(
verbose_name=_("Affects indigenous people?"),
help_text=_("Does the project affect indigenous people?")
help_text=_("Does the project affect indigenous communities?")
)
# 1.5.6.1
@ -165,7 +213,10 @@ class CaseStudy(models.Model):
verbose_name=_("Affects Indigenous - Details"),
help_text=_("What group of indigenous people does the community belong\
to?"),
max_length=256
max_length=256,
default=None,
null=True,
blank=True
)
# 1.6
@ -176,6 +227,28 @@ class CaseStudy(models.Model):
choices=PROJECT_STATUS_CHOICES
)
# 1.7
start_year = models.IntegerField(
verbose_name=_("Start year"),
help_text=_("Select the year the project was started. \
If the project hasn't begun, select the projected start year."),
choices=YEAR_CHOICES,
default=None,
null=True,
blank=True
)
# 1.8
completion_year = models.IntegerField(
verbose_name=_("Completion year"),
help_text=_("Select the year the project was completed. \
If the project hasn't finished, select the projected completion year."),
choices=YEAR_CHOICES,
default=None,
null=True,
blank=True
)
# 1.9
synopsis = models.TextField(
verbose_name=_("Synopsis"),
@ -193,24 +266,287 @@ class CaseStudy(models.Model):
here.")
)
# 1.15
# 1.11
project_owners = models.CharField(
verbose_name=_("Project and facility owners"),
help_text=_("List companies or organisations that own the project and/or facilities. Separate with a comma."),
max_length=120,
default=None,
null=True,
blank=True
)
# 1.12
shareholders = models.CharField(
verbose_name=_("Shareholders of the project owners"),
help_text=_("List shareholders of the project owners you've just listed. Separate with a comma."),
max_length=120,
default=None,
null=True,
blank=True
)
# 1.13
financial_institutions = models.CharField(
verbose_name=_("Financial institutions"),
help_text=_("List banks and other financial institutions that have or are considering extending loans \
or guarantees to the project. Separate with a comma."),
max_length=120,
default=None,
null=True,
blank=True
)
# 1.14
energy_customers = models.CharField(
verbose_name=_("Energy consumers"),
help_text=_("List any wholesale energy customers that take energy from the development. E.g. 'national \
grids' or private energy suppliers."),
max_length=120,
default=None,
null=True,
blank=True
)
# 1.15.1
image = models.ImageField(
verbose_name=_("Image")
)
# 1.16
video = models.URLField(
verbose_name=_("Video"),
max_length=43
# 1.15.2
image_caption = models.CharField(
verbose_name=_("Image caption"),
max_length=500,
default=None,
null=True,
)
# 1.18
# 1.15.3
image_credit = models.CharField(
verbose_name=_("Image credit(s)"),
max_length=200,
default=None,
null=True,
)
# 1.16.1
video = models.URLField(
verbose_name=_("YouTube Video"),
help_text=_("Copy the URL to a related YouTube™ video that relates to the case study."),
max_length=43,
validators=[validators.YoutubeURLValidator()]
)
# 1.16.2
video_caption = models.CharField(
verbose_name=_("Video caption"),
max_length=500,
default=None,
null=True,
)
# 1.16.3
video_credit = models.CharField(
verbose_name=_("Video credit(s)"),
max_length=500,
default=None,
null=True,
)
# 1.17.1
media_coverage_mainstream = models.TextField(
verbose_name=_("Links to media reports"),
help_text=_("Provide any links to mainstream media coverage."),
max_length=500,
default=None,
null=True,
)
# 1.17.2
media_coverage_independent = models.TextField(
verbose_name=_("Independent grassroots reports"),
help_text=_("Provide any links to grassroots/independent media coverage."),
max_length=500,
default=None,
null=True,
)
# 1.18.1
community_voices = models.TextField(
verbose_name=_("Community Voices"),
help_text=_("Add any direct quotes from members of the community that\
help_text=_("Add any direct quotes from members of the community that \
relate to this project")
)
# 1.18.2
direct_comms = models.TextField(
verbose_name=_("Reports of direct communications"),
help_text=_("Add any reports of direct communication between community members and \
representatives of developers/companies/investors."),
max_length=500,
default=None,
null=True,
)
# 1.18.3
social_media_links = models.TextField(
verbose_name=_("Social media links"),
help_text=_("Add any links to social media accounts directly relating to the project."),
max_length=500,
default=None,
null=True,
blank=True
)
##
# Second Screen
##
# 2.1.1
generation_technology = models.CharField(
verbose_name=_("Generation technology"),
help_text=_("Select the type of renewable energy generation that most applies to this case study."),
max_length=4,
choices=GENERATION_TECHNOLOGY_CHOICES,
default=None,
null=True,
blank=True
)
# 2.1.1.12
# Should be filled in if 2.1.1 was answered as biogas or biomass.
biomass_detail = models.CharField(
verbose_name=_("Generation technology detail"),
help_text=_("If you selected biogas or biomass, please describe the feedstock (where the fuel came from e.g. \
corn, algae, anaerobic digestion, commercial waste etc)"),
max_length=200,
default=None,
null=True,
blank=True
)
# 2.1.1.14
generation_technology_other = models.CharField(
verbose_name=_("Other generation type"),
help_text=_("If you selected other, please specify the generation technology (e.g. tidal, wave etc)"),
max_length=200,
default=None,
null=True,
blank=True
)
# 2.1.2
total_generation_capacity = models.PositiveIntegerField(
verbose_name=_("Total generation capacity (in kW)"),
help_text=_("Please enter the total generation capacity of the project in kW"),
default=None,
null=True,
blank=True,
)
# 2.1.3 - autocomplete_light queryset
# 2.1.4
total_investment = models.IntegerField(
verbose_name=_("Total investment (in USD)"),
help_text=_("The approximate total investment for the project in USD."),
default=None,
null=True,
blank=True
)
# 2.1.5
technical_or_economic_details = models.CharField(
verbose_name=_("Additional technical or economic details"),
help_text=_("Specify any additional technical or economic details relating to the project."),
max_length=500,
default=None,
null=True,
blank=True
)
# 2.2 - Only if 1.2.2 selected
# 2.2.1
power_technology = models.CharField(
verbose_name=_("Power technology"),
help_text=_("Select the related energy technology."),
max_length=2,
choices=POWER_TECHNOLOGY_CHOICES,
default=None,
null=True,
blank=True
)
power_technology_other = models.CharField(
verbose_name=_("Other power technology"),
help_text=_("If you answered 'others', please specify the power technologies."),
max_length=128,
default=None,
null=True,
blank=True
)
energy_storage_capacity = models.IntegerField(
verbose_name=_("Energy storage capacity"),
help_text=_("Enter the total capacity of the energy storage system."),
default=None,
null=True,
blank=True
)
##
# Third Screen
##
##
# Fourth Screen
##
# 4.1
official_project_documents = models.FileField(
verbose_name=_("Official project documents"),
help_text=_("Attach any legal or official documents that relate to the project."),
default=None,
null=True,
blank=True
)
# 4.2
other_documents = models.FileField(
verbose_name=_("Other documents"),
help_text=_("Attach any other documents that relate to the project."),
default=None,
null=True,
blank=True
)
# 4.3
definition_of_affected_territories = models.CharField(
verbose_name=_("Definition of affected territories"),
help_text=_("In your own words, define the territories that the project will affect."),
max_length=512,
default=None,
null=True,
blank=True
)
# 4.4
shown_on_other_platforms = models.NullBooleanField(
verbose_name=_("Show on other platforms?"),
help_text=_("Tick the box if you would like us to show this case study on other social media platforms"),
default=None,
null=True,
blank=True
)
# 4.4.1
shown_on_other_platforms_detail = models.CharField(
verbose_name=_("Show on other platforms - Detail"),
help_text=_("List the social media platforms that you would like us to specifically publish the case study on"),
max_length=128,
null=True,
blank=True
)
def __str__(self):
"""The String representation of the case study. (Entry name with country name.)"""
return "%s in %s" % (self.entry_name, self.country.name)
@ -227,3 +563,7 @@ class CaseStudy(models.Model):
self.slug = slugify(self.entry_name)
# Continue normal save method by calling original save method.
super(CaseStudy, self).save(*args, **kwargs)
def get_video_id(self):
"""Gets the 11 character YouTube video ID from the video field."""
return parse.parse_qs(parse.urlparse(self.video).query)["v"][0]

View File

@ -1,4 +1,10 @@
from moderation import moderation
from moderation.moderator import GenericModerator
from apps.map.models import CaseStudy
moderation.register(CaseStudy) # Uses default moderation settings
class CaseStudyModerator(GenericModerator):
notify_user = True
auto_approve_for_superusers = True
moderation.register(CaseStudy, CaseStudyModerator)

View File

@ -17,7 +17,7 @@
<div class="container-fluid">
<div class="row" style="background-color: #e3f3fd;">
<div class="col-lg-8 border-top-0">
<a class="btn btn-info" style="margin:15px 0;padding-left:20px;left:-10px;position:absolute;" href="{% url 'index' %}" role="button"><- {% trans "Back to Map" %}</a>
<a class="btn btn-info" style="margin:15px 0;padding-left:20px;left:-10px;position:absolute;" href="{% url 'index' %}" role="button"><i class="fa fa-arrow-left" aria-hidden="true"></i> {% trans "Back to Map" %}</a>
<div style="margin-top:70px;padding:0 20px;">
<h1>{{case_study.entry_name}}</h1>
<p>{{case_study.synopsis}}</p>
@ -33,13 +33,13 @@
<span class="badge badge-pill bg-info">{{case_study.country.name}}</span>
</br>
<small class="text-muted">Created {{case_study.date_created|naturaltime}} by <i>{{case_study.author.}}</i></small>
</div>
</div>
<a class="btn btn-primary btn-lg float-right" href="#" role="button">Get Involved</a>
</div>
</div>
<div class="col-lg-4">
<div class="embed-responsive embed-responsive-16by9">
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/ScMzIvxBSi4?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/{{case_study.get_video_id}}?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>
</div>
</div>
</div>

View File

@ -31,4 +31,95 @@
// See GeometryField source (static/leaflet/leaflet.forms.js) to override more stuff...
});
</script>
<!-- Conditional logic for hiding and un-hiding fields. -->
<script type="text/javascript">
// Here we define the fields we need to conditionally toggle.
// TODO: Move this knowledge out of the template
var conditionalFields = [{
"field": "#id_land_ownership",
"showHide": ["#div_id_land_ownership_details"],
"condition": "OTH"
},
{
"field": "#id_power_technology",
"showHide": ["#div_id_power_technology_other"],
"condition": "OT"
},
{
"field": "#id_sector_of_economy",
"showHide": ["#div_id_generation_technology",
"#div_id_biomass_detail",
"#div_id_generation_technology_other",
"#div_id_total_generation_capacity",
"#div_id_total_investment",
"#div_id_technical_or_economic_details"],
"condition": ["WND","SOL","HYD"]
}];
// Here we define the checkboxes that we need to use to
// conditionally toggle fields - they use slightly different
// logic as they rely on the 'checked' attribute rather than value.
var conditionalCheckboxes = [{
"checkbox": "#id_affects_indigenous",
"showHide": "#div_id_affects_indigenous_detail"
}];
// Define a function that hides the field and then creates a listener to toggle the field.
// Takes a single conditionalField dictionary with (field, showHide and condition).
function addConditionalField(item) {
hideAll(item.showHide);
$(item.field).change(function(){
// Get the value of the option
var value = $(this).val();
// Check the value matches any of the conditions.
if (isInArray(value, item.condition)){
showAll(item.showHide);
} else {
hideAll(item.showHide);
}
});
}
// This function does the same as addConditionalField except it checks the status of
// checkboxes instead of fields.
function addConditionalCheckbox(item) {
$(item.showHide).hide();
$(item.checkbox).change(function(){
if ($(this).is(":checked")) {
$(item.showHide).show();
} else {
$(item.showHide).hide();
}
});
}
// Helper functions
function show(tag) {
$(tag).show();
}
function hide(tag) {
$(tag).hide();
}
function showAll(tags) {
tags.forEach(show);
}
function hideAll(tags) {
tags.forEach(hide);
}
function isInArray(value, array) {
return array.indexOf(value) > -1;
}
conditionalFields.forEach(addConditionalField);
conditionalCheckboxes.forEach(addConditionalCheckbox);
</script>
{% endblock %}

View File

@ -100,13 +100,13 @@
}).addTo(map);
});
// Add an on-click listener for map click events. Show popup with button to submit a casestudy
map.on('click', function(e) {
var popup = L.popup()
.setLatLng(e.latlng)
.setContent("<a class='btn btn-primary btn-sm' href='{% url 'create' %}?lat="+e.latlng.lat+"&lng="+e.latlng.lng+"' role='button'>{% trans "Submit a Case Study" %}</a>")
.openOn(map);
});
<!--// Add an on-click listener for map click events. Show popup with button to submit a casestudy-->
<!--map.on('click', function(e) {-->
<!--var popup = L.popup()-->
<!--.setLatLng(e.latlng)-->
<!--.setContent("<a class='btn btn-primary btn-sm' href='{% url 'create' %}?lat="+e.latlng.lat+"&lng="+e.latlng.lng+"' role='button'>{% trans "Submit a Case Study" %}</a>")-->
<!--.openOn(map);-->
<!--});-->
}
</script>
{% endblock %}

5
apps/map/validators.py Normal file
View File

@ -0,0 +1,5 @@
from django.core.validators import RegexValidator
class YoutubeURLValidator(RegexValidator):
regex = r'https?:\/\/(((www.)?youtube.com\/((watch\?v=)|(watch\/)))|(youtu.be\/))([A-z0-9]{1,11}).+'