ojuso-map/apps/map/forms.py
2018-11-24 16:54:39 +00:00

412 lines
16 KiB
Python

from django import forms
from django.urls import reverse, reverse_lazy
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, HTML, Fieldset, Div
from crispy_forms.bootstrap import Tab, TabHolder, PrependedText, FormActions
from dal import autocomplete
from leaflet.forms.widgets import LeafletWidget
from apps.files.models import File, ImageFile
from .models import CaseStudy, SpatialRefSys, PointOfInterest
from .widgets import JSONFileListWidget
class MinimumZoomWidget(LeafletWidget):
geometry_field_class = 'MinimumZoomField'
class PointOfInterest(forms.models.ModelForm):
def __init__(self, *args, **kwargs):
super(PointOfInterest, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_id = 'case-study-form'
self.helper.form_class = 'form-horizontal'
self.helper.form_method = 'post'
self.helper.form_action = 'add'
self.helper.label_class = 'col-lg-2'
self.helper.field_class = 'col-lg-10'
self.helper.include_media = False
self.helper.form_action = reverse('point-of-interest-form')
self.helper.add_input(Submit('submit', _('Submit'), css_class='btn-success center-block'))
class Meta:
model = PointOfInterest
widgets = {
'location': MinimumZoomWidget(attrs={
'settings_overrides': {
'SCALE': False
}
}),
}
fields = [
'title',
'location',
'synopsis',
'link',
]
class BaseCaseStudyForm(forms.models.ModelForm):
"""Base form class for the CaseStudy model."""
def __init__(self, *args, **kwargs):
super(BaseCaseStudyForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_id = 'case-study-form'
self.helper.form_class = 'form-horizontal'
self.helper.form_method = 'post'
self.helper.form_action = 'add'
self.helper.label_class = 'col-lg-2'
self.helper.field_class = 'col-lg-8'
self.helper.include_media = False
class Meta:
model = CaseStudy
fields = '__all__'
widgets = {
'location': MinimumZoomWidget(attrs={
'settings_overrides': {
'SCALE': False
}
}),
}
class ShortCaseStudyForm(BaseCaseStudyForm):
"""Short version of the CaseStudy form."""
def __init__(self, *args, **kwargs):
super(ShortCaseStudyForm, self).__init__(*args, **kwargs)
self.helper.form_action = reverse('short-form')
self.helper.add_input(Submit('submit', _('Submit'), css_class='btn-success center-block'))
class Meta(BaseCaseStudyForm.Meta):
fields = [
'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',
'affected_communities',
'project_status',
'synopsis',
'full_description',
'video',
'media_coverage_mainstream',
'media_coverage_independent',
'community_voices'
]
class BootstrapClearableFileInput(forms.ClearableFileInput):
template_name = 'map/forms/widgets/file.html'
class LongCaseStudyForm(BaseCaseStudyForm):
"""Long version of the CaseStudy form."""
images = forms.FileField(
widget=BootstrapClearableFileInput(attrs={
'url': reverse_lazy('files:upload'),
'field': 'images_files',
}), required=False
)
images_files = forms.ModelMultipleChoiceField(
queryset=ImageFile.objects.all(),
widget=JSONFileListWidget(),
required=False
)
official_project_documents = forms.FileField(
widget=BootstrapClearableFileInput(attrs={
'url': reverse_lazy('files:upload'),
'field': 'official_project_documents_files',
}), required=False
)
official_project_documents_files = forms.ModelMultipleChoiceField(
queryset=File.objects.all(),
widget=JSONFileListWidget(),
required=False
)
other_documents = forms.FileField(
widget=BootstrapClearableFileInput(attrs={
'url': reverse_lazy('files:upload'),
'field': 'other_documents_files',
}), required=False
)
other_documents_files = forms.ModelMultipleChoiceField(
queryset=File.objects.all(),
widget=JSONFileListWidget(),
required=False
)
shapefiles = forms.FileField(
widget=BootstrapClearableFileInput(attrs={
'url': reverse_lazy('files:upload'),
'field': 'shapefiles_files',
}), required=False
)
shapefiles_files = forms.ModelMultipleChoiceField(
queryset=File.objects.all(),
widget=JSONFileListWidget(),
required=False
)
coordinate_reference_system = forms.ModelChoiceField(
queryset=SpatialRefSys.objects.all(),
widget=autocomplete.ModelSelect2(url='srs-autocomplete'),
initial=4326,
)
POSITIVE_CASE_TYPE_HELP = {
'CREP': _("We are using the World Wind Energy Association's Community Power definition, \
which is that a community project is one where at least \
two of the following three criteria are met:<br> \
1. Local stakeholders own the majority or all of a project,<br> \
2. Voting control rests with the community-based organization,<br> \
3. The majority of social and economic benefits are distributed locally."),
'EACP': _(""),
'PSEP': _(""),
'CORS': _("The extraction of non-renewable resources, such as iron, copper, \
rare-earth elements or other minerals and metals used in \
renewable technologies, directly from the Earth is by definition \
an unsustainable practice. Despite this, the extraction of such elements \
this way for use in the renewable energy transition is, to an extent, \
a necessary evil in the immediate term. Bearing this in mind, \
a case involving extraction may be considered 'positive' if it helps \
to reduce, overall, the need for more extraction; if it drastically \
reduces ecological harms often caused by mining and does not infringe \
on areas of high biodiversity; and if it meets outstanding social \
and human rights standards that are enjoyed and affirmed by \
host communities and other stakeholders. Such social standards include: \
ensuring communities, and especially indigenous peoples, \
enjoy their right to Free Prior and Informed Consent, \
which includes the right to reject projects; abiding by \
the UN's guiding principles on Business and Human Rights; \
full collaboration with the Extractive Industries Transparency Initiative, \
assuring excellence in the transparency of project financing, \
tax affairs and other transactions; the highest labour standards; \
equitable distribution of any benefits accruing from mining; \
respect for the rule of law and the constitutional rights of citizens \
in host countries."),
}
SECTOR_HELP = {
'RN': _("including electricity, heat or combined heat and power generation"),
'PG': "",
'SM': _("including supply of minerals and/or manufacturing/processing of equipment used in the renewable energy economy")
}
def add_explanatory_text(self, model_choices, explanatory_text):
return [
(
choice[0],
mark_safe('<b>%s</b><br><span class="text-muted">%s</span>' %
(choice[1], explanatory_text[choice[0]])
)
) for choice in model_choices
]
def __init__(self, *args, **kwargs):
super(LongCaseStudyForm, self).__init__(*args, **kwargs)
self.fields['positive_case_type'] = forms.ChoiceField(
widget=forms.RadioSelect(),
choices=self.add_explanatory_text(
CaseStudy.POSITIVE_CASE_TYPE_CHOICES,
self.POSITIVE_CASE_TYPE_HELP,
),
required=False
)
self.fields['sector_of_economy'] = forms.ChoiceField(
widget=forms.RadioSelect(),
choices=self.add_explanatory_text(
CaseStudy.SECTOR_CHOICES,
self.SECTOR_HELP
),
required=False
)
self.fields['project_owners'].required = True
self.fields['shareholders'].required = True
self.helper.form_action = reverse('long-form')
self.helper.layout = Layout(
TabHolder(
Tab(_("Basic information"),
'entry_name',
'location',
'country',
'area_of_land',
'land_ownership',
'land_ownership_details',
'location_context',
'type_of_ecosystem',
'describe_ecosystem',
'people_affected_indigenous',
'people_affected_other',
'project_status',
'synopsis',
'full_description',
'images',
'images_files',
'video',
'video_caption',
'video_credit',
Fieldset(
_("Ownership and finance"),
'project_owners',
'consultants_contractors',
'shareholders',
'financial_institutions',
'financial_institutions_other',
'energy_customers'
),
Fieldset(
_("Media reports and other communications"),
'media_coverage_mainstream',
'media_coverage_independent',
'community_voices',
'direct_comms',
'social_media_links'
),
FormActions(
HTML("<a class='btn btn-primary btnNext pull-right'>"+_("Next")+"</a>")
)
),
Tab(
_("Technical and economic analysis"),
'sector_of_economy',
Fieldset(
_("Power Generation Questions"),
'generation_technology',
'biomass_detail',
'generation_technology_other',
'total_generation_capacity',
'generation_equipment_supplier',
'total_investment',
'technical_or_economic_details',
css_id="power_generation_questions"
),
Fieldset(
_("Power Grids/Energy Storage Questions"),
'power_technology',
'power_technology_other',
'energy_storage_capacity',
'maximum_power_output',
'discharge_time',
'contractor_or_supplier_of_technology',
'approximate_total_investment',
'additional_technical_details',
css_id="power_grids_energy_storage_questions"
),
Fieldset(
_("Mineral/Commodity Questions"),
'minerals_or_commodities',
'minerals_or_commodities_other',
'use_in_energy_economy',
'use_in_energy_economy_other',
'project_life_span',
'size_of_concessions',
'projected_production_of_commodities',
'type_of_extraction',
'associated_infrastructure',
css_id="mineral_commodity_questions"
),
FormActions(
HTML("<a class='btn btn-primary btnPrevious'>"+_("Previous")+"</a>"),
HTML("<a class='btn btn-primary btnNext pull-right'>"+_("Next")+"</a>")
)
),
Tab(
_("Socio-environmental analysis"),
'positive_or_negative',
Fieldset(
_("Positive Case Questions"),
'positive_case_type',
'socioeconomic_benefits',
'project_status_detail',
'obstacles_and_hindrances',
'identified_partnerships',
css_id="positive_case_questions"
),
Fieldset(
_("Negative Case Questions"),
'negative_case_reasons',
'negative_case_reasons_other',
'negative_socioenvironmental_impacts',
'isolated_or_widespread',
'when_did_organising_start',
'who_has_been_involved',
'participation_mechanisms',
'potential_partnerships',
'wants_conversation_with_ojuso',
css_id="negative_case_questions"
),
Div(
'key_actors_involved',
css_id="common_questions"
),
FormActions(
HTML("<a class='btn btn-primary btnPrevious'>"+_("Previous")+"</a>"),
HTML("<a class='btn btn-primary btnNext pull-right'>"+_("Next")+"</a>")
)
),
Tab(
_("Contact details"),
'contact_email',
'contact_phone',
'contact_website',
PrependedText('contact_twitter', '@', placeholder='username'),
'contact_facebook',
'contact_other',
FormActions(
HTML("<a class='btn btn-primary btnPrevious'>"+_("Previous")+"</a>"),
HTML("<a class='btn btn-primary btnNext pull-right'>"+_("Next")+"</a>")
)
),
Tab(
_("Uploads"),
'official_project_documents',
'official_project_documents_files',
'other_documents',
'other_documents_files',
'shapefiles',
'shapefiles_files',
'coordinate_reference_system',
'name_of_territory_or_area',
'shown_on_other_platforms',
'shown_on_other_platforms_detail',
FormActions(
HTML("<a class='btn btn-primary btnPrevious'>"+_("Previous")+"</a>"),
Submit('submit', _('Submit'), css_class="btn-success pull-right")
)
)))
class Meta(BaseCaseStudyForm.Meta):
exclude = ('approved',)
class Media:
js = (
'files/upload.js',
)