ojuso-map/apps/map/models.py

1140 lines
37 KiB
Python
Raw Normal View History

import datetime
from urllib import parse
from django.contrib.auth.models import User
from django.contrib.gis.db import models
from django.db import connection
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
from django_extensions.db.fields import AutoSlugField
from django_countries.fields import CountryField
2017-11-18 16:54:44 +00:00
from multiselectfield import MultiSelectField
2018-03-31 05:29:25 +00:00
from phonenumber_field.modelfields import PhoneNumberField
from . import validators
2018-04-14 02:40:42 +00:00
class CaseStudyDraft(models.Model):
author = models.ForeignKey(
2018-04-23 05:15:33 +00:00
User, on_delete=models.CASCADE
2018-04-14 02:40:42 +00:00
)
2018-05-30 03:15:39 +00:00
created = models.DateTimeField(auto_now_add=True)
2018-04-14 02:40:42 +00:00
data = models.TextField()
2018-05-30 03:15:39 +00:00
def __str__(self):
return "{0.author.username}, {0.created:%Y-%m-%d %H:%M}".format(self)
2018-04-14 02:40:42 +00:00
class SpatialRefSys(connection.ops.spatial_ref_sys()):
def __str__(self):
return self.__unicode__()
def __unicode__(self):
return '{0.auth_name}:{0.auth_srid} {0.name}'.format(self)
class Meta:
proxy = True
verbose_name = "spatial reference system"
class CaseStudyQuerySet(models.QuerySet):
def approved(self):
return self.filter(
approved=True
)
class CaseStudy(models.Model):
"""Model for case studies submitted to the Ojuso Platform"""
approved = models.BooleanField(default=False)
# Choice lists for drop-downs
POSITIVE_NEGATIVE_CHOICES = (
2018-11-24 16:54:39 +00:00
('P', _('There is/was an organising process in favour of the project')),
('N', _('There is/was an organising process against the project')),
('X', _('There is/was no organising process')),
('U', _('Unsure/unknown'))
)
LAND_OWNERSHIP_CHOICES = (
2018-11-24 16:54:39 +00:00
('PRI', _('Private land')),
('PUB', _('Public/state land')),
('COM', _('Community/communal/customary land')),
('CON', _('Contested/in conflict')),
('OTH', _('Other')),
)
LOCATION_CONTEXT_CHOICES = (
('RUR', _('Rural')),
('URB', _('Urban')),
2018-03-29 10:41:09 +00:00
('MIX', _('Mixed')),
)
TYPE_OF_ECOSYSTEM_CHOICES = (
2019-03-18 16:41:58 +00:00
('MARINE', _('Marine (e.g. ocean, sea)')),
('FRESH', _('Freshwater (e.g. river, lake)')),
2019-03-18 16:41:58 +00:00
('FOREST', _('Forest/jungle')),
('AGRI', _('Agricultural land')),
('GRASS', _('Grassland')),
2019-03-18 16:41:58 +00:00
('DESERT', _('Desert (tundra, ice or sand)')),
('WETLND', _('Wetland (marsh, mangrove, peat Soil)')),
('URBAN', _('Urban'))
)
2018-11-24 16:54:39 +00:00
AFFECTED_COMMUNITIES_CHOICES = (
2019-03-18 16:41:58 +00:00
('INDIG', _('Indigenous people(s)')),
2018-11-24 16:54:39 +00:00
('AFRO', _('Afro-descendants')),
('MIG', _('Migrants')),
('REF', _('Refugees')),
('OTHER', _('Other communities or identities')),
)
PROJECT_STATUS_CHOICES = (
('INIT', _('Initial/conceptual')),
2018-11-24 16:54:39 +00:00
('PROJCD', _('In planning and design')),
('FAIL', _('Failed')),
('UCONST', _('Under construction')),
('EXSTNG', _('In operation')),
('DECOMM', _('Undergoing decommissioning')),
2018-11-25 13:48:52 +00:00
('END', _('Decommissioned')),
)
2018-03-31 09:52:06 +00:00
FINANCIAL_INSTITUTIONS = (
('AfDB', _('African Development Bank (AfDB)')),
('BADEA', _('Arab Bank for Economic Development in Africa (BADEA)')),
('ADB', _('Asian Development Bank (ADB)')),
('AIIB', _('Asian Infrastructure Investment Bank (AIIB)')),
('BSTDB', _('Black Sea Trade and Development Bank (BSTDB)')),
('CAF', _('Corporacion Andina de Fomento / Development Bank of Latin America (CAF)')),
('CDB', _('Caribbean Development Bank (CDB)')),
('CABEI', _('Central American Bank for Economic Integration (CABEI)')),
('EADB', _('East African Development Bank (EADB)')),
('ETDB', _('Economic Cooperation Organization Trade and Development Bank (ETDB)')),
('EDB', _('Eurasian Development Bank (EDB)')),
('EBRD', _('European Bank for Reconstruction and Development (EBRD)')),
('EC', _('European Commission (EC)')),
('EIB', _('European Investment Bank (EIB)')),
('IADB', _('Inter-American Development Bank Group (IDB, IADB)')),
('IFAD', _('International Fund for Agricultural Development (IFAD)')),
('IIB', _('International Investment Bank (IIB)')),
('IsDB', _('Islamic Development Bank (IsDB)')),
2019-03-18 16:41:58 +00:00
('FMO', _('Nederlandse Financieringsmaatschappij voor Ontwikkelingslanden NV (Netherlands Development Finance Company, FMO)')),
2018-03-31 09:52:06 +00:00
('NDB', _('New Development Bank (NDB) (formerly BRICS Development Bank)')),
('NDF', _('The Nordic Development Fund')),
('NIB', _('Nordic Investment Bank (NIB)')),
('OFID', _('OPEC Fund for International Development (OFID)')),
('BOAD', _('West African Development Bank (BOAD)')),
('WB', _('World Bank')),
)
2018-11-26 22:34:06 +00:00
SECTOR_CHOICES = (
('RN', _('Renewable energy generation project')),
('PG', _('Energy networks')),
('ST', _('Energy storage facilities')),
('SM', _('Mining related to the renewable energy economy')),
('MA', _('Manufacturing and/or processing of equipment'))
)
2018-11-24 17:58:08 +00:00
GENERATION_TYPE_CHOICES = (
('POW', _('Electricity')),
('HOT', _('Heat/Cold')),
('CHP', _('Combined Heat/Cold and Power (CHP, CCP or CCHP)')),
2018-11-24 17:58:08 +00:00
)
GENERATION_TECHNOLOGY_CHOICES = (
2018-11-24 17:58:08 +00:00
('BIO', _('Bio-energy')),
('GEOT', _('Geothermal electricity')),
(_('Hydro'), (
('uHYD', _('Micro hydro (<100kW)')),
('SHYD', _('Small-scale hydro (100kW-1MW)')),
2018-11-24 17:58:08 +00:00
('MHYD', _('Medium-scale hydro (1-30MW)')),
('LHYD', _('Large-scale hydro (>30MW - often not considered renewable)')),
)),
2018-11-24 17:58:08 +00:00
(_('Marine'), (
('WAVE', _('Wave')),
('TSTR', _('Tidal stream')),
('TBAR', _('Tidal barrage/lagoon')),
('TOTH', _('Other')),
)),
2018-11-24 17:58:08 +00:00
(_('Solar'), (
('SSPV', _('Small-scale photovoltaic (<500kW)')),
('LSPV', _('Large-scale photovoltaic (>500kW)')),
2019-03-21 19:24:46 +00:00
( 'CSP', _('Solar power tower')),
2018-11-24 17:58:08 +00:00
('PARA', _('Parabolic trough (open or enclosed)')),
('FRES', _('Fresnel reflector')),
('STIR', _('Dish Stirling')),
)),
(_('Wind'), (
('SSWE', _('Small-scale wind (<500kW)')),
('LSWE', _('Large-scale wind (>500kW)'))
)),
('OTHR', _('Other'))
)
POWER_TECHNOLOGY_CHOICES = (
('PT', _('Electrical power transmission/distribution')),
2018-11-24 17:58:08 +00:00
('HN', _('Heat networks')),
('OT', _('Other')),
)
2017-11-18 16:54:44 +00:00
TYPE_OF_EXTRACTION_CHOICES = (
2018-03-28 03:06:04 +00:00
('SUR', _('Surface (open pit/open cast/open cut mining)')),
2017-11-18 16:54:44 +00:00
('SUB', _('Sub-surface (underground mining)')),
('SEA', _('Seabed mining')),
('URB', _('Urban mining/recycling'))
)
MINERAL_COMMODITY_CHOICES = (
('ALU', _('Aluminium (Bauxite)')),
('ARS', _('Arsenic')),
('BER', _('Beryllium')),
('CAD', _('Cadmium')),
('CHR', _('Chromium')),
('COK', _('Coking coal (for steel)')),
2017-11-18 16:54:44 +00:00
('COP', _('Copper')),
('GAL', _('Gallium')),
('GER', _('Germanium')),
('GLD', _('Gold')),
('HRE', _(
'Heavy rare earth elements (gadolinium, terbium, dysprosium, holmium,'
' erbium, thulium, ytterbium, lutetium, yttrium, scandium)')),
2017-11-18 16:54:44 +00:00
('IRN', _('Iron')),
('LRE', _(
'Light rare earth elements (lanthanum, cerium, praseodymium, neodymium,'
' promethium, samarium, europium)')),
2017-11-18 16:54:44 +00:00
('LED', _('Lead')),
('LIT', _('Lithium')),
('MAN', _('Manganese')),
('MER', _('Mercury')),
('MOL', _('Molybdenum')),
('NIC', _('Nickel')),
('NIO', _('Niobium')),
('PGM', _(
'Platinum group metals (ruthenium, rhodium, palladium, osmium,'
' iridium, and platinum)')),
2017-11-18 16:54:44 +00:00
('RHE', _('Rhenium')),
('SIL', _('Silicon')),
('SIV', _('Silver')),
('TAN', _('Tantalum')),
('TEL', _('Tellurium')),
('THA', _('Thallium')),
('TIN', _('Tin')),
('TIT', _('Titanium')),
('TUN', _('Tungsten')),
('VAN', _('Vanadium')),
('ZNC', _('Zinc')),
('OTR', _('Other'))
)
USE_IN_ENERGY_ECONOMY_CHOICES = (
('CPV', _('Concentrated solar power (CSP) tower')),
('EPT', _('Electrical power transmission/distribution infrastructure')),
2018-11-24 21:09:35 +00:00
('ESS', _('Energy storage')),
('GGM', _('Geothermal')),
('HGM', _('Hydropower')),
('HNT', _('Heat networks')),
('SPM', _('Solar photovoltaic')),
2018-11-24 21:09:35 +00:00
('STM', _('Solar thermal systems')),
('WTM', _('Wind power')),
('ESS', _("Don't know")),
('OTR', _('Other'))
)
MANUFACTURING_TYPE_CHOICES = (
('GENERATE', _('Manufacturing of renewable energy generation equipment')),
('TRANSSTORE', _('Manufacturing of energy transmission or storage equipment')),
('RECYCLE', _('Recycling/reusing equipment or raw materials')),
2018-11-24 21:09:35 +00:00
('DISPOSAL', _('Disposal of equipment')),
('OTHER', _('Other')),
)
MANUFACTURING_RELATED_CHOICES = (
('PV', _('Solar PV')),
2019-03-18 16:41:58 +00:00
('CSP', _('Concentrated solar power (CSP)')),
2018-11-24 21:09:35 +00:00
('WIND', _('Wind power')),
('HYDRO', _('Hydropower')),
('GEO', _('Geothermal')),
2019-04-21 12:28:03 +00:00
('TRANSMIT', _('Electrical power transmission/distribution infrastructure')),
2018-11-24 21:09:35 +00:00
('STORE', _('Energy storage')),
('HEAT', _('Heat networks')),
('OTHER', _('Other')),
('IDK', _('Unknown')),
)
MANUFACTURING_FACTORS_CHOICES = (
('LAND', _('Land use')),
('LABOR', _('Labor rights')),
('ENVIRO', _('Environmental factors')),
('LIFECYCLE', _('Lifecycle management')),
('OWN', _('Ownership')),
('OTHER', _('Other(s)')),
2017-11-18 16:54:44 +00:00
)
POSITIVE_CASE_TYPE_CHOICES = (
2018-11-25 13:48:52 +00:00
('CREP', _('Community project (co-)owned by individuals')),
('EACP', _(
'Community project owned by not-for-profit organizations and/or serving'
' the public interest')),
2018-11-25 13:48:52 +00:00
('PSEP', _('Public/state (federal, state, municipal) project')),
('CORS', _('Circular economy project / Reuse / Recycling')),
2017-11-18 16:54:44 +00:00
)
NEGATIVE_CASE_REASONS_CHOICES = (
('VOLR', _('Violation of land rights')),
('VOHR', _(
'Violation of fundamental human rights, indigenous rights and/or other'
' collective rights')),
('EIMP', _(
2019-04-21 12:28:03 +00:00
'Environmental impacts (severe impacts on ecosystems / violation of laws,'
' plans or programs of environmental conservation, etc.)')),
('NCUL', _(
'Negative cultural impacts (erosion/destruction of bio-cultural heritage,'
' impacts on sacred land, etc.)')),
('AGGR', _(
'Aggression/threats to community members opposed to the project,'
' collaboration with organized crime, etc.')),
2017-11-18 16:54:44 +00:00
('ALAB', _('Abusive labour practices')),
('CRUP', _(
'Corruption and/or irregular permitting or contracting, conflicts of'
' interest, etc.')),
2017-11-18 16:54:44 +00:00
)
# 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
##
# User who submitted case study
author = models.ForeignKey(
User,
on_delete=models.SET_NULL,
blank=True,
null=True,
editable=False
)
# Date and time of submission
date_created = models.DateTimeField(auto_now_add=True, null=False)
# Slug derived from entry_name, used in urls for SEO
2017-11-18 16:54:44 +00:00
slug = AutoSlugField(populate_from=['entry_name'], editable=False)
2019-03-04 20:17:06 +00:00
# Language this case study is written in
language = models.CharField(max_length=16, blank=True)
# Long or short case study?
form_type = models.CharField(max_length=16, blank=True)
2018-11-25 13:48:52 +00:00
##
# Territory info
##
location = models.PointField(
verbose_name=_("Project location")
)
shapefiles_label = _(
"Do you have geographic information files about the territory impacted by"
" this project?"
)
shapefiles_help_text = _(
"For example, of the limits of the land within which a project is taking"
" place, or of sites of particular importance. You can upload data in"
" different formats (ESRI Shapefiles with file extensions like .cpg, .dbf,"
" .prj, .qpj, .shp, .shx., or GeoPackage gpkg, GeoJSON, KML, GML, etc.)."
" Write to database@ojuso.org if you need help."
)
2018-11-25 13:48:52 +00:00
shapefiles = models.ManyToManyField(
'files.File',
related_name='shapefile_for',
verbose_name=shapefiles_label,
help_text=shapefiles_help_text,
2018-11-25 13:48:52 +00:00
blank=True
)
coordinate_reference_system = models.ForeignKey(
SpatialRefSys,
null=True,
blank=True,
default=4326,
on_delete=models.PROTECT
)
name_of_territory_or_area = models.CharField(
verbose_name=_("Name of territory or area"),
max_length=512,
blank=True
)
##
2017-11-18 16:54:44 +00:00
# First Screen - Basic information
##
# 1.1
entry_name = models.CharField(
verbose_name=_("Project name"),
help_text=_("Please write the local name, followed by any translated name if necessary."),
max_length=128
)
# 1.4
country = CountryField(
verbose_name=_("Country"),
help_text=_("Please select the country of the project.")
)
# 1.5.1
area_of_land = models.IntegerField(
verbose_name=_("Approximate land area"),
help_text=_("The area of land covered by the project (km²)")
)
# 1.5.2
land_ownership = models.CharField(
2019-03-18 16:41:58 +00:00
verbose_name=_("Land ownership/tenure"),
help_text=_("What type of ownership/tenure does the land fall under?"),
max_length=3,
choices=LAND_OWNERSHIP_CHOICES
)
# 1.5.3
2018-11-24 16:54:39 +00:00
land_ownership_details = models.TextField(
2019-03-18 16:41:58 +00:00
verbose_name=_("Land ownership/tenure details"),
help_text=_("<p class='text-muted'>Please specify details about land ownership,"
" including conflicting claims, unrecognized customary rights, "
" conflicts around land lease or purchase contracts, etc."
2019-03-18 16:41:58 +00:00
""
"<p class='text-muted'>We understand this is a difficult question, so"
" please try to provide <b>just the information you know</b>.</p>"),
max_length=256,
blank=True,
)
# 1.5.4
location_context = models.CharField(
verbose_name=_("Location"),
help_text=_(
"Please select the context that is most applicable to this case study."),
max_length=3,
choices=LOCATION_CONTEXT_CHOICES
)
# 1.5.5
2018-03-29 10:41:09 +00:00
type_of_ecosystem = MultiSelectField(
verbose_name=_("Type(s) of ecosystem"),
max_length=56,
choices=TYPE_OF_ECOSYSTEM_CHOICES,
2017-11-18 16:54:44 +00:00
blank=True
)
# 1.5.5.3
2017-11-18 16:54:44 +00:00
describe_ecosystem = models.TextField(
verbose_name=_("Please describe the ecosystem."),
)
2018-11-24 16:54:39 +00:00
affected_communities = MultiSelectField(
verbose_name=_("Communities or identities present in the project area"),
max_length=50,
choices=AFFECTED_COMMUNITIES_CHOICES,
blank=True
)
people_affected_other = models.TextField(
2018-11-26 22:34:06 +00:00
verbose_name=_("Communities or identities further detail"),
help_text=_("Please describe further the communities or identities present in the project area."),
blank=True
)
# 1.6
project_status = models.CharField(
2018-11-24 16:54:39 +00:00
verbose_name=_("Status of project"),
max_length=6,
choices=PROJECT_STATUS_CHOICES
)
# 1.7
start_year = models.IntegerField(
2018-11-24 16:54:39 +00:00
verbose_name=_("Construction start year"),
help_text=_("Please select the year project construction began."
"If the project is not yet in construction, select the assumed"
" start year as detailed in company information or media."),
choices=YEAR_CHOICES,
blank=True,
null=True
)
# 1.8
completion_year = models.IntegerField(
2018-11-24 16:54:39 +00:00
verbose_name=_("Operation start year"),
help_text=_(
"Please select the year the project's operation and maintenance (O&M) phase"
" began. If the project is not yet in operation, select the year operation "
" is expected to begin as detailed in company information or media."),
choices=YEAR_CHOICES,
default=None,
null=True,
blank=True
)
# 1.9
synopsis = models.TextField(
verbose_name=_("Project synopsis"),
help_text=_("Please briefly summarise the project. (Maximum 500 characters.)"),
max_length=500
)
# 1.10
full_description = models.TextField(
2019-03-18 16:41:58 +00:00
verbose_name=_("Full description"),
help_text=_("Please describe the project in full. Separate paragraphs with two"
" new lines. Please add as much detail as you feel is necessary"
" here.")
)
# 1.11
project_owners = models.TextField(
verbose_name=_("Project owners"),
help_text=_("Please list companies or organisations that own the project."
" Write each name in a new line."),
blank=True
)
2018-11-24 16:54:39 +00:00
consultants_contractors = models.TextField(
verbose_name=_("Consultants and contractors"),
help_text=_("Please list consultants, planners or organisations that are doing"
" the planning, construction, operation or maintenance work relating"
" to the project and/or facilities. Separate each with a new line."),
2018-12-02 00:31:04 +00:00
blank=True
2018-11-24 16:54:39 +00:00
)
# 1.12
shareholders = models.TextField(
verbose_name=_("Shareholders of the project owners"),
help_text=_("List the shareholders of the company/companies that own the"
" project, if you have this information. Separate with a new line."),
blank=True
)
2018-03-31 09:52:06 +00:00
# 1.13.1
financial_institutions = MultiSelectField(
verbose_name=_("Financial institutions"),
help_text=_("Please select any financial institutions (public or private) that"
" have, or are considering extending loans or guarantees to the"
" project."),
2018-03-31 09:52:06 +00:00
choices=FINANCIAL_INSTITUTIONS,
blank=True
)
# 1.13.2
financial_institutions_other = models.TextField(
verbose_name=_("Financial institutions other"),
help_text=_("Please list any other financial institutions not listed above."
" Separate with a new line."),
blank=True
)
# 1.15.1, 1.15.2, 1.15.3
images = models.ManyToManyField(
'files.ImageFile',
related_name='image_for',
verbose_name=_("Images"),
blank=True
)
# 1.16.1
video = models.URLField(
verbose_name=_("Video URL"),
help_text=_("Copy the URL to a YouTube or Vimeo video that relates to the case study."),
max_length=80,
validators=[validators.YouTubeOrVimeoValidator()],
blank=True
)
# 1.16.2
video_caption = models.CharField(
verbose_name=_("Video caption"),
2018-03-29 10:41:09 +00:00
max_length=240,
blank=True,
)
# 1.16.3
video_credit = models.CharField(
verbose_name=_("Video credit(s)"),
2018-03-29 10:41:09 +00:00
max_length=240,
blank=True,
)
2018-03-26 01:11:37 +00:00
# 1.17.1
media_coverage_mainstream = models.TextField(
verbose_name=_("Links to media reports"),
help_text=_("Please provide any links to mainstream media coverage."),
blank=True,
)
# 1.17.2
media_coverage_independent = models.TextField(
verbose_name=_("Independent grassroots reports"),
help_text=_("Please provide any links to grassroots/independent media coverage."),
blank=True,
)
# 1.18.1
community_voices = models.TextField(
verbose_name=_("Community Voices"),
help_text=_(
"Please add any direct quotes from members of the community that relate"
" to this project."),
blank=True,
)
# 1.18.2
direct_comms = models.TextField(
verbose_name=_("Reports of direct communications"),
help_text=_(
"Please add any reports of direct communication between community members"
" and representatives of developers/companies/investors. If you have files"
" to upload, you can do this in 'other documents' on the 'uploads' tab."),
blank=True,
)
# 1.18.3
social_media_links = models.TextField(
verbose_name=_("Social media links"),
help_text=_(
"Please add any links to social media accounts directly relating"
" to the project."),
max_length=500,
blank=True,
)
##
2017-11-18 16:54:44 +00:00
# Second Screen - Technical and economic analysis
##
2018-11-26 22:34:06 +00:00
sector_of_economy = models.CharField(
verbose_name=_("Sector of renewable energy economy"),
2018-11-26 22:34:06 +00:00
max_length=3,
choices=SECTOR_CHOICES
)
energy_details = models.CharField(
verbose_name=_("Technology type"),
help_text=_("Please provide more information about the type of technology this case study focuses on."),
2018-11-26 22:34:06 +00:00
max_length=200,
blank=True
)
2018-11-24 17:58:08 +00:00
## Energy generation project
generation_type = models.CharField(
verbose_name=_('What kind of energy is generated?'),
2018-11-24 17:58:08 +00:00
max_length=4,
choices=GENERATION_TYPE_CHOICES,
blank=True
)
generation_technology = models.CharField(
verbose_name=_("Generation technology"),
help_text=_("Please select the type of renewable energy generation that most"
" applies to this case study."),
max_length=4,
choices=GENERATION_TECHNOLOGY_CHOICES,
blank=True
)
2018-11-24 17:58:08 +00:00
# Should be filled in if generation_technology was answered as bio-energy
biomass_detail = models.CharField(
verbose_name=_("Bio-energy feedstock"),
help_text=_("<div class='text-muted'>"
"<p>Please describe the source of the fuel and how it is processed/used."
" Please consider:</p>\n"
"<ul>\n"
"<li>where the fuel came from e.g. corn, forestry, algae,"
" commercial food waste, landfill gas, sewage, livestock farm, etc.</li>\n"
"<li>how it is processed e.g. direct-fired, co-firing with other renewable"
" input, gasification, bacterial decomposition (anaerobic digestion, AD), "
" pyrolysis, artificial photosynthesis, fuel cell, etc.</li>\n"
"</ul>\n"
"<p>We do not expect users to know this information, but if you do "
" it may be useful to give a fuller picture.</p>"
"</div>"),
max_length=200,
blank=True
)
2018-11-26 22:34:06 +00:00
# 1.14
energy_customers = models.TextField(
verbose_name=_("Energy service consumers/off-takers"),
help_text=_(
"Please list the customers that buy energy from the project, e.g. the"
" national grid provider, or private companies. Also mention whether"
" credits are being sold in the carbon markets. Separate with a new line."
),
2018-11-26 22:34:06 +00:00
blank=True
)
# 2.1.2
total_generation_capacity = models.PositiveIntegerField(
verbose_name=_("Total generation capacity (kW)"),
blank=True,
null=True
)
# 2.1.4
total_investment = models.IntegerField(
verbose_name=_("Total investment (in USD)"),
help_text=_(
"Please enter the approximate total investment for the project in"
" United State Dollars (USD)."),
blank=True,
null=True
)
2017-11-18 16:54:44 +00:00
# 2.2 - Power Grids / Energy Storage
# 2.2.1
power_technology = models.CharField(
verbose_name=_("Power technology"),
max_length=2,
choices=POWER_TECHNOLOGY_CHOICES,
blank=True
)
2017-11-18 16:54:44 +00:00
# 2.2.1.4
power_technology_other = models.CharField(
2018-11-24 18:30:58 +00:00
verbose_name=_("Further information about power technology"),
max_length=128,
blank=True
)
2018-03-29 10:48:57 +00:00
energy_storage_capacity = models.DecimalField(
2018-11-24 18:30:58 +00:00
verbose_name=_("Total storage capacity (kWh)"),
2018-03-29 10:48:57 +00:00
max_digits=20,
decimal_places=3,
blank=True,
null=True,
)
2018-11-24 18:30:58 +00:00
energy_transmission_capacity = models.DecimalField(
verbose_name=_("Total transmission or distribution capacity (kW)"),
2018-11-24 18:30:58 +00:00
max_digits=20,
2018-03-29 10:48:57 +00:00
decimal_places=3,
blank=True,
2017-11-18 16:54:44 +00:00
null=True,
)
2018-11-26 22:34:06 +00:00
# TODO: Auto-completion based on previous entries so we can query case-studies with the same answer.
contractor_or_supplier_of_technology = models.TextField(
verbose_name=_('Supplier of technology'),
help_text=_("Please list companies that supply the energy generation equipment"
" - e.g. Siemens Gamesa, GE, Alstom, Vestas, Hanwha Q CELLS,"
" Mitsubishi, First Solar, Jinko Solar, Trina Solar,"
" Suzlon Energy, Statkraft, Shanghai Electric,"
" Ballard Power Systems, Panasonic, etc."),
blank=True,
2017-11-18 16:54:44 +00:00
)
# 2.2.5
2018-11-24 18:30:58 +00:00
additional_technical_details = models.TextField(
2017-11-18 16:54:44 +00:00
verbose_name=_("Additional technical or economic details"),
help_text=_(
"Please add any additional details that may help to explain the technical"
" and economic aspects of this case study."),
2017-11-18 16:54:44 +00:00
blank=True
)
##
# Mining
##
2018-11-24 21:09:35 +00:00
2017-11-18 16:54:44 +00:00
minerals_or_commodities = models.CharField(
2018-11-24 21:09:35 +00:00
verbose_name=_("Primary mineral mined"),
help_text=_("What mineral commodity is primarily mined here?"),
2017-11-18 16:54:44 +00:00
max_length=3,
choices=MINERAL_COMMODITY_CHOICES,
blank=True
)
2018-11-24 21:09:35 +00:00
minerals_or_commodities_other = models.TextField(
verbose_name=_("Other mineral commodities"),
help_text=_(
"Please enter any mineral commodities not in the list."
" Separate each with a new line."),
2017-11-18 16:54:44 +00:00
blank=True
)
2018-11-24 21:09:35 +00:00
use_in_energy_economy = MultiSelectField(
2018-03-28 03:06:04 +00:00
verbose_name=_("Potential use in renewable energy economy"),
2018-11-24 21:09:35 +00:00
max_length=128,
2017-11-18 16:54:44 +00:00
choices=USE_IN_ENERGY_ECONOMY_CHOICES,
blank=True
)
use_in_energy_economy_other = models.CharField(
2018-11-24 21:09:35 +00:00
verbose_name=_('Other'),
2017-11-18 16:54:44 +00:00
max_length=128,
blank=True
)
project_life_span = models.CharField(
verbose_name=_("Project life span"),
help_text=_("e.g. 12 years of production, 15 years overall"),
max_length=200,
2018-05-23 17:15:30 +00:00
blank=True
2017-11-18 16:54:44 +00:00
)
size_of_concessions = models.CharField(
2018-11-24 21:09:35 +00:00
verbose_name=_("Size of concessions (land/marine area)"),
help_text=_(
"Please describe the size of concession(s) granted to company/companies"
" (e.g. 'one concession of 2,300 hectares (23km²)')"),
2017-11-18 16:54:44 +00:00
max_length=200,
blank=True
2017-11-18 16:54:44 +00:00
)
projected_production_of_commodities = models.CharField(
2018-11-24 21:09:35 +00:00
verbose_name=_("Estimated production of key commodities"),
help_text=_(
'Please describe the projected production of commodities per annum and'
' overall.<br>\n'
'For example, "40 million tonnes of iron ore per year",'
' "200 million tonnes over 5 year life of mine"."'),
2017-11-18 16:54:44 +00:00
max_length=256,
blank=True
2017-11-18 16:54:44 +00:00
)
type_of_extraction = models.CharField(
verbose_name=_("Type of extraction"),
2018-03-28 03:06:04 +00:00
max_length=3,
2017-11-18 16:54:44 +00:00
choices=TYPE_OF_EXTRACTION_CHOICES,
blank=True
)
associated_infrastructure = models.CharField(
verbose_name=_("Associated infrastructure in the locality"),
help_text=_("Please list any associated infrastructure in the locality"
" (e.g. tailings dams / mine waste storage and treatment facilities;"
" ore processing facilities; smelting facilities;"
" hydroelectric dams / energy infrastructure;"
" transport infrastructure e.g. roads or rail)."),
2017-11-18 16:54:44 +00:00
max_length=256,
blank=True
)
2018-11-24 21:09:35 +00:00
## Manufacturing
manufacturing_type = models.CharField(
verbose_name=_("Which of the following options best describes this case?"),
max_length=16,
choices=MANUFACTURING_TYPE_CHOICES,
blank=True
)
manufacturing_description = models.TextField(
verbose_name=_("Description"),
help_text=_(
"Please briefly describe manufacturing process and components/outputs."
" (less than 500 characters)."),
2018-11-24 21:09:35 +00:00
max_length=500,
blank=True
)
manufacturing_related_tech = MultiSelectField(
verbose_name=_("What technology is this case related to?"),
max_length=128,
choices=MANUFACTURING_RELATED_CHOICES,
blank=True
)
manufacturing_factors = MultiSelectField(
verbose_name=_(
"Please choose the factors that make this case remarkable, "
"in a positive or negative way."),
2018-11-24 21:09:35 +00:00
max_length=128,
choices=MANUFACTURING_FACTORS_CHOICES,
blank=True
)
manufacturing_factors_description = models.TextField(
verbose_name=_("Please describe these factors."),
2018-11-24 21:09:35 +00:00
blank=True
)
manufacturing_ownership = models.TextField(
2019-04-21 12:28:03 +00:00
verbose_name=_("Describe the ownership structure of the project and its relation with the local community."),
2018-11-24 21:09:35 +00:00
blank=True
)
##
2018-11-25 13:48:52 +00:00
# Socio-economic analysis
##
2018-11-25 13:48:52 +00:00
positive_or_negative = models.CharField(
verbose_name=_("What is the relationship of local community organization(s) to this project?"),
max_length=1,
choices=POSITIVE_NEGATIVE_CHOICES
)
2018-11-26 22:34:06 +00:00
positive_case_type = MultiSelectField(
2018-11-25 13:48:52 +00:00
verbose_name=_('What kind of case is this entry about?'),
2017-11-18 16:54:44 +00:00
choices=POSITIVE_CASE_TYPE_CHOICES,
2018-11-26 22:34:06 +00:00
max_length=32,
2017-11-18 16:54:44 +00:00
blank=True,
)
2018-11-25 13:48:52 +00:00
negative_case_reasons = MultiSelectField(
verbose_name=("What kind of case is this entry about?"),
choices=NEGATIVE_CASE_REASONS_CHOICES,
2017-11-18 16:54:44 +00:00
blank=True
)
2018-11-25 13:48:52 +00:00
socioeconomic_benefits = models.TextField(
verbose_name=_('Socio-economic impacts'),
2018-03-31 05:29:25 +00:00
blank=True
)
2017-11-18 16:54:44 +00:00
2018-11-25 13:48:52 +00:00
negative_socioenvironmental_impacts = models.TextField(
verbose_name=_("Describe the socio-environmental impacts (positive and negative):"),
help_text=_(
"Please provide a detailed description of the socio-environmental impacts"
" (all relevant details, such as type of ecosystem, presence of any"
" existing reserve in the area, biodiversity impacts, new protection of"
" lands/waters, total geographic footprint of the project,"
" tenure system affected in the case of land grabs, etc.)."),
2018-03-31 05:29:25 +00:00
blank=True
)
2017-11-18 16:54:44 +00:00
2018-11-25 13:48:52 +00:00
isolated_or_widespread = models.TextField(
verbose_name=_("Is the project part of developments which are causing a cumulative effect?"),
help_text=_(
"Is this an isolated project or are there similar projects in the same"
" geographic area? If so, can you please describe them? Is there an"
" analysis of cumulative or synergetic effects?"),
2018-03-31 05:29:25 +00:00
blank=True
)
2017-11-18 16:54:44 +00:00
2018-11-25 13:48:52 +00:00
key_actors_involved = models.TextField(
verbose_name=_('Key actors involved (individual/organisational)'),
2018-03-31 05:29:25 +00:00
blank=True
)
2017-11-18 16:54:44 +00:00
2018-11-25 13:48:52 +00:00
project_status_detail = models.TextField(
verbose_name=_('Current status of the case'),
help_text=_("Please describe the current situation and likely future scenarios."),
2018-03-31 05:29:25 +00:00
blank=True
)
2017-11-18 16:54:44 +00:00
2018-11-25 13:48:52 +00:00
obstacles_and_hindrances = models.TextField(
verbose_name=_('Current status of the organizing process around this case'),
help_text=_('Please describe the status of the organizing process, including the obstacles and hindrances faced.'),
max_length=512,
2018-03-31 05:29:25 +00:00
blank=True
)
2017-11-18 16:54:44 +00:00
2018-11-25 13:48:52 +00:00
identified_partnerships = models.CharField(
verbose_name=_('Identified partnerships'),
help_text=_('Are you, or the organizing process that you represent, looking for partnerships,'
' or have any clearly identified need? If so, please describe and we will try'
' to connect you to appropriate partners.'),
2018-11-25 13:48:52 +00:00
max_length=256,
2017-11-18 16:54:44 +00:00
blank=True
)
# 3.2.1.9
negative_case_reasons_other = models.CharField(
verbose_name=_("Other reason for negative case"),
2019-03-18 16:41:58 +00:00
help_text=_("For negative impacts you need to focus on substantive impacts on vulnerable groups."),
2017-11-18 16:54:44 +00:00
max_length=512,
blank=True
)
# 3.2.4.1
when_did_organising_start = models.CharField(
verbose_name=_("When did local organising efforts begin?"),
help_text=_(
"Before the project started? During project implementation?"
" After project implementation? Please describe in your own words."),
2017-11-18 16:54:44 +00:00
max_length=512,
blank=True
)
# 3.2.4.2
who_has_been_involved = models.TextField(
2017-11-18 16:54:44 +00:00
verbose_name=_("Which communities, groups and organisations have been involved?"),
blank=True
2017-11-18 16:54:44 +00:00
)
# 3.2.4.3
participation_mechanisms = models.TextField(
2017-11-18 16:54:44 +00:00
verbose_name=_("What mechanisms of participation have been used?"),
help_text=_("e.g. direct action, local referendums, legal cases,"
" letters or petitions, etc."),
2017-11-18 16:54:44 +00:00
blank=True
)
# 3.2.7
wants_conversation_with_ojuso = models.BooleanField(
verbose_name=_(
"Would you like to have a conversation with the <b>ojuso</b> team?"),
help_text=_(
"This would be a conversation about challenging or engaging related"
" developers, companies and investors."),
default=False
2017-11-18 16:54:44 +00:00
)
2018-11-25 13:48:52 +00:00
##
2018-11-25 13:48:52 +00:00
# Contact details
##
contact_email = models.EmailField(
verbose_name=_('Email address'),
blank=True
)
contact_phone = PhoneNumberField(
verbose_name=_('Phone number'),
help_text=_('Please include the international prefix, beginning with "+".'),
blank=True
)
contact_website = models.URLField(
verbose_name=_('Website'),
blank=True
)
contact_twitter = models.CharField(
verbose_name=_('Twitter username'),
max_length=50,
blank=True
)
contact_facebook = models.URLField(
verbose_name=_('Facebook page'),
blank=True
)
contact_other = models.TextField(
verbose_name=_('Other contact details'),
blank=True
)
##
# Uploads
##
# 4.1
2018-04-23 05:15:33 +00:00
official_project_documents = models.ManyToManyField(
'files.File',
related_name='official_project_document_for',
verbose_name=_("Official project documents"),
help_text=_("Please attach any legal or official documents that relate to the project."),
2017-11-18 16:54:44 +00:00
blank=True,
)
# 4.2
2018-04-23 05:15:33 +00:00
other_documents = models.ManyToManyField(
'files.File',
related_name='other_document_for',
verbose_name=_("Other documents"),
help_text=_("Please attach any other documents that relate to the project."),
2017-11-18 16:54:44 +00:00
blank=True,
)
# 4.4
shown_on_other_platforms = models.BooleanField(
2018-03-31 05:33:35 +00:00
verbose_name=_("Is this case study shown on other platforms?"),
default=True
)
# 4.4.1
2018-03-31 05:33:35 +00:00
shown_on_other_platforms_detail = models.TextField(
verbose_name=_("Shown on other platforms - Detail"),
help_text=_("Please provide links to other places the case study appears."),
blank=True
)
objects = CaseStudyQuerySet.as_manager()
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)
def save(self, *args, **kwargs):
"""
Override the save method to create a slug when the model is created.
Slug is only created and never modified as we are basing our URLs on it and
don't want it to change - ever.
"""
if not self.pk:
# Newly created object, so set slug
self.slug = slugify(self.entry_name)
super(CaseStudy, self).save(*args, **kwargs)
def is_video_youtube(self):
return self.video.count("youtube.com") > 0
def get_youtube_id(self):
"""Gets the 11 character YouTube video ID from the video field."""
return parse.parse_qs(parse.urlparse(self.video).query)["v"][0]
2017-11-18 16:54:44 +00:00
def is_video_vimeo(self):
return self.video.count("vimeo.com") > 0
def get_vimeo_id(self):
"""Gets the 11 number video ID from the video field."""
return parse.urlparse(self.video).path
class Meta:
verbose_name_plural = 'case studies'
2018-10-12 22:50:27 +00:00
class PointOfInterestQuerySet(models.QuerySet):
def approved(self):
return self.filter(
approved=True
)
2018-10-12 22:50:27 +00:00
class PointOfInterest(models.Model):
2018-10-12 22:56:27 +00:00
class Meta:
verbose_name_plural = 'points of interest'
def __str__(self):
return self.title
objects = PointOfInterestQuerySet.as_manager()
2018-10-12 22:50:27 +00:00
author = models.ForeignKey(
User,
models.SET_NULL,
blank=True,
null=True,
editable=False
2018-10-12 22:50:27 +00:00
)
date_created = models.DateTimeField(auto_now_add=True, null=False)
2018-10-12 22:56:27 +00:00
slug = AutoSlugField(populate_from=['title'], editable=False)
2018-10-12 22:50:27 +00:00
approved = models.BooleanField(default=False)
title = models.CharField(max_length=128)
location = models.PointField()
synopsis = models.TextField()
link = models.URLField()