Add registration and login templates plus UI stuff, moderation

This commit is contained in:
Livvy Mackintosh
2017-10-08 21:21:51 +01:00
parent f8dc44b4a6
commit 049ca29e77
64 changed files with 18607 additions and 159 deletions

0
apps/contact/__init__.py Normal file
View File

11
apps/contact/forms.py Normal file
View File

@ -0,0 +1,11 @@
from envelope.forms import ContactForm
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
class ContactForm(ContactForm):
def __init__(self, *args, **kwargs):
super(ContactForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit('submit', 'Submit',
css_class='btn-lg pull-right'))

View File

@ -0,0 +1,21 @@
{% extends "base_page.html" %}
{% load bootstrap3 %}
{% load crispy_forms_tags %}
{% load envelope_tags %}
{% block page_name %}Contact{% endblock %}
{% block content %}
<div class="container">
<div class="page-lead">
<h2>Contact</h2>
<p class="lead">Send us your thoughts and feedback.</p>
</div>
{% bootstrap_messages %}
<form action="{% url 'contact' %}" method="post">
{% csrf_token %}
{% antispam_fields %}
{% crispy form %}
</form>
</div>
{% endblock %}

3
apps/contact/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

7
apps/contact/urls.py Normal file
View File

@ -0,0 +1,7 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.ContactView.as_view(), name='contact'),
]

12
apps/contact/views.py Normal file
View File

@ -0,0 +1,12 @@
from braces.views import FormMessagesMixin
from envelope.views import ContactView
from django.utils.translation import ugettext_lazy as _
from .forms import ContactForm
class ContactView(FormMessagesMixin, ContactView):
form_invalid_message = _(u"There was an error in the contact form.")
form_valid_message = _(u"Thank you for your message.")
form_class = ContactForm

View File

@ -1,6 +1,12 @@
from django.contrib import admin
from moderation.admin import ModerationAdmin
from leaflet.admin import LeafletGeoAdmin
from .models import CaseStudy
admin.site.register(CaseStudy, LeafletGeoAdmin)
class CaseStudyAdmin(ModerationAdmin, LeafletGeoAdmin):
pass
admin.site.register(CaseStudy, CaseStudyAdmin)

View File

@ -6,15 +6,15 @@ from leaflet.forms.widgets import LeafletWidget
from .models import CaseStudy
class CaseStudyForm(forms.ModelForm):
class BaseCaseStudyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(CaseStudyForm, self).__init__(*args, **kwargs)
super(BaseCaseStudyForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = 'case-study-form'
self.helper.form_class = 'form-horizontal'
self.helper.form_method = 'post'
self.helper.form_action = 'submit'
self.helper.form_action = 'add'
self.helper.label_class = 'col-lg-2'
self.helper.field_class = 'col-lg-8'
self.helper.add_input(Submit('submit', 'Submit'))
@ -22,4 +22,33 @@ class CaseStudyForm(forms.ModelForm):
class Meta:
model = CaseStudy
fields = '__all__'
widgets = {'location': LeafletWidget()}
widgets = {'location': LeafletWidget(attrs={})}
class ShortCaseStudyForm(BaseCaseStudyForm):
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',
'affects_indigenous',
'affects_indigenous_detail',
'project_status',
'synopsis',
'full_description',
'image',
'community_voices'
]
class LongCaseStudyForm(BaseCaseStudyForm):
class Meta(BaseCaseStudyForm.Meta):
fields = '__all__'

View File

@ -0,0 +1,169 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-06 15:59
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0003_auto_20170521_0643'),
]
operations = [
migrations.RemoveField(
model_name='casestudy',
name='affects_indigenous',
),
migrations.RemoveField(
model_name='casestudy',
name='affects_indigenous_reason',
),
migrations.RemoveField(
model_name='casestudy',
name='associated_companies',
),
migrations.RemoveField(
model_name='casestudy',
name='commodities',
),
migrations.RemoveField(
model_name='casestudy',
name='description',
),
migrations.RemoveField(
model_name='casestudy',
name='financiers',
),
migrations.RemoveField(
model_name='casestudy',
name='generation_type',
),
migrations.RemoveField(
model_name='casestudy',
name='important_lenders',
),
migrations.RemoveField(
model_name='casestudy',
name='like_to_engage_developer',
),
migrations.RemoveField(
model_name='casestudy',
name='like_to_engage_investors',
),
migrations.RemoveField(
model_name='casestudy',
name='link_to_forum',
),
migrations.RemoveField(
model_name='casestudy',
name='project_name',
),
migrations.RemoveField(
model_name='casestudy',
name='proposed_completion',
),
migrations.RemoveField(
model_name='casestudy',
name='proposed_start',
),
migrations.RemoveField(
model_name='casestudy',
name='references',
),
migrations.RemoveField(
model_name='casestudy',
name='supply_chain',
),
migrations.AddField(
model_name='casestudy',
name='Affects Indigenous - Details',
field=models.CharField(default='', help_text='What group of indigenous people does the community belong to?', max_length=256),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Affects indigenous people?',
field=models.BooleanField(default=False, help_text='Does the project affect indigenous people?'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Approximate land area',
field=models.IntegerField(default=0, help_text='The area of land covered by the project (in km²)'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Community Voices',
field=models.TextField(default='', help_text='Add any direct quotes from members of the community that relate to this project'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Describe the ecosystem',
field=models.CharField(default='', help_text='In your own words, add more detail about the ecosystem.', max_length=256),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Entry Name',
field=models.CharField(default='', help_text='Enter the name of the entry. This should usually be the name of project.', max_length=128),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Full Description',
field=models.TextField(default='', help_text='Describe the project in full. Separate paragraphs with a new line Please add as much detail as you feel is necessary here.'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Land ownership',
field=models.CharField(choices=[('PRI', 'Private Land'), ('PUB', 'Public Land'), ('COM', 'Community Land'), ('OTH', 'Other')], default='', help_text='What type of ownership does the land fall under?', max_length=3),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Land ownership details',
field=models.CharField(default='', help_text='Add any details and other remarks about the land ownership', max_length=256),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Location',
field=models.CharField(choices=[('RUR', 'Rural'), ('URB', 'Urban')], default=None, help_text='Select the context that is most applicable to this case study.', max_length=1),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Positive or negative?',
field=models.CharField(choices=[('POS', 'Positive'), ('NEG', 'Negative')], default=None, help_text='Is the case study a positive case or a negative case?', max_length=1),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Sector of economy',
field=models.CharField(choices=[('Renewable Energy Generation', (('WND', 'Wind'), ('SOL', 'Solar'), ('HYD', 'Hydro'))), ('PG', 'Power Grids'), ('SM', 'Supply of Minerals')], default=None, help_text='Which sector of the renewable energy economy is most relevant?', max_length=2),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Status of Project',
field=models.CharField(choices=[('EXSTNG', 'Existing Project'), ('UCONST', 'Under Construction'), ('PROJCD', 'Projected Project')], default=None, help_text='What is the status of the current project?', max_length=6),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Synopsis',
field=models.TextField(default=None, help_text='Briefly describe the project. This will be displayed at the top of the case study page. Maximum 500 chars (about 3½ tweets)', max_length=500),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='Type of ecosystem',
field=models.CharField(choices=[('Water Based', (('MARINE', 'Marine (e.g. Ocean, Sea)'), ('FRESH', 'Freshwater (e.g. Freshwater, Lake)'))), ('Land Based', (('FOREST', 'Forest/Jungle'), ('AGRI', 'Agricultural Land'), ('GRASS', 'Grassland'), ('DESERT', 'Desert (Tundra, Ice or Sand)'), ('WETLND', 'Wetland (Marsh, Mangrove, Peat Soil)'), ('URBAN', 'Urban')))], default=None, help_text='Select the most relevant type of ecosystem.', max_length=6),
preserve_default=False,
),
]

View File

@ -0,0 +1,165 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-06 20:33
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0004_auto_20171006_1559'),
]
operations = [
migrations.RemoveField(
model_name='casestudy',
name='Affects Indigenous - Details',
),
migrations.RemoveField(
model_name='casestudy',
name='Affects indigenous people?',
),
migrations.RemoveField(
model_name='casestudy',
name='Approximate land area',
),
migrations.RemoveField(
model_name='casestudy',
name='Community Voices',
),
migrations.RemoveField(
model_name='casestudy',
name='Describe the ecosystem',
),
migrations.RemoveField(
model_name='casestudy',
name='Entry Name',
),
migrations.RemoveField(
model_name='casestudy',
name='Full Description',
),
migrations.RemoveField(
model_name='casestudy',
name='Land ownership',
),
migrations.RemoveField(
model_name='casestudy',
name='Land ownership details',
),
migrations.RemoveField(
model_name='casestudy',
name='Location',
),
migrations.RemoveField(
model_name='casestudy',
name='Positive or negative?',
),
migrations.RemoveField(
model_name='casestudy',
name='Sector of economy',
),
migrations.RemoveField(
model_name='casestudy',
name='Status of Project',
),
migrations.RemoveField(
model_name='casestudy',
name='Synopsis',
),
migrations.RemoveField(
model_name='casestudy',
name='Type of ecosystem',
),
migrations.AddField(
model_name='casestudy',
name='affects_indigenous',
field=models.BooleanField(default=None, help_text='Does the project affect indigenous people?', verbose_name='Affects indigenous people?'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='affects_indigenous_detail',
field=models.CharField(default=None, help_text='What group of indigenous people does the community belong to?', max_length=256, verbose_name='Affects Indigenous - Details'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='area_of_land',
field=models.IntegerField(default=None, help_text='The area of land covered by the project (in km²)', verbose_name='Approximate land area'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='community_voices',
field=models.TextField(default=None, help_text='Add any direct quotes from members of the community that relate to this project', verbose_name='Community Voices'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='describe_ecosystem',
field=models.CharField(default=None, help_text='In your own words, add more detail about the ecosystem.', max_length=256, verbose_name='Describe the ecosystem'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='entry_name',
field=models.CharField(default=None, help_text='Enter the name of the entry. This should usually be the name of project.', max_length=128, verbose_name='Entry Name'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='full_description',
field=models.TextField(default=None, help_text='Describe the project in full. Separate paragraphs with a new line Please add as much detail as you feel is necessary here.', verbose_name='Full Description'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='land_ownership',
field=models.CharField(choices=[('PRI', 'Private Land'), ('PUB', 'Public Land'), ('COM', 'Community Land'), ('OTH', 'Other')], default=None, help_text='What type of ownership does the land fall under?', max_length=3, verbose_name='Land ownership'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='land_ownership_details',
field=models.CharField(default=None, help_text='Add any details and other remarks about the land ownership', max_length=256, verbose_name='Land ownership details'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='location_context',
field=models.CharField(choices=[('RUR', 'Rural'), ('URB', 'Urban')], default=None, help_text='Select the context that is most applicable to this case study.', max_length=1, verbose_name='Location'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='positive_or_negative',
field=models.CharField(choices=[('POS', 'Positive'), ('NEG', 'Negative')], default=None, help_text='Is the case study a positive case or a negative case?', max_length=1, verbose_name='Positive or negative?'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='project_status',
field=models.CharField(choices=[('EXSTNG', 'Existing Project'), ('UCONST', 'Under Construction'), ('PROJCD', 'Projected Project')], default=None, help_text='What is the status of the current project?', max_length=6, verbose_name='Status of Project'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='sector_of_economy',
field=models.CharField(choices=[('Renewable Energy Generation', (('WND', 'Wind'), ('SOL', 'Solar'), ('HYD', 'Hydro'))), ('PG', 'Power Grids'), ('SM', 'Supply of Minerals')], default=None, help_text='Which sector of the renewable energy economy is most relevant?', max_length=2, verbose_name='Sector of economy'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='synopsis',
field=models.TextField(default=None, help_text='Briefly describe the project. This will be displayed at the top of the case study page. Maximum 500 chars (about 3½ tweets)', max_length=500, verbose_name='Synopsis'),
preserve_default=False,
),
migrations.AddField(
model_name='casestudy',
name='type_of_ecosystem',
field=models.CharField(choices=[('Water Based', (('MARINE', 'Marine (e.g. Ocean, Sea)'), ('FRESH', 'Freshwater (e.g. Freshwater, Lake)'))), ('Land Based', (('FOREST', 'Forest/Jungle'), ('AGRI', 'Agricultural Land'), ('GRASS', 'Grassland'), ('DESERT', 'Desert (Tundra, Ice or Sand)'), ('WETLND', 'Wetland (Marsh, Mangrove, Peat Soil)'), ('URBAN', 'Urban')))], default=None, help_text='Select the most relevant type of ecosystem.', max_length=6, verbose_name='Type of ecosystem'),
preserve_default=False,
),
]

View File

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-07 13:49
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0005_auto_20171006_2033'),
]
operations = [
migrations.AlterField(
model_name='casestudy',
name='location_context',
field=models.CharField(choices=[('RUR', 'Rural'), ('URB', 'Urban')], help_text='Select the context that is most applicable to this case study.', max_length=3, verbose_name='Location'),
),
migrations.AlterField(
model_name='casestudy',
name='positive_or_negative',
field=models.CharField(choices=[('P', 'Positive'), ('N', 'Negative')], help_text='Is the case study a positive case or a negative case?', max_length=1, verbose_name='Positive or negative?'),
),
migrations.AlterField(
model_name='casestudy',
name='sector_of_economy',
field=models.CharField(choices=[('Renewable Energy Generation', (('WND', 'Wind'), ('SOL', 'Solar'), ('HYD', 'Hydro'))), ('PG', 'Power Grids'), ('SM', 'Supply of Minerals')], help_text='Which sector of the renewable energy economy is most relevant?', max_length=3, verbose_name='Sector of economy'),
),
]

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-07 14:23
from __future__ import unicode_literals
from django.db import migrations
import django_extensions.db.fields
class Migration(migrations.Migration):
dependencies = [
('map', '0006_auto_20171007_1349'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='slug',
field=django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from=['entry_name']),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-07 15:02
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0007_casestudy_slug'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='date_created',
field=models.DateTimeField(auto_now=True),
),
]

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-07 15:44
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('map', '0008_casestudy_date_created'),
]
operations = [
migrations.AddField(
model_name='casestudy',
name='video',
field=models.URLField(default="", max_length=43, verbose_name='Video'),
preserve_default=False,
),
migrations.AlterField(
model_name='casestudy',
name='image',
field=models.ImageField(upload_to='', verbose_name='Image'),
),
]

View File

@ -1,21 +1,67 @@
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
class CaseStudy(models.Model):
"""Model for case studies submitted to the Ojuso Platform"""
# Choice lists for dropdowns
SUPPLY_CHAIN_CHOICES = (
('A', 'Option A'),
('B', 'Option B'),
# Choice lists for drop-downs
SECTOR_CHOICES = (
(_('Renewable Energy Generation'), (
('WND', _('Wind')),
('SOL', _('Solar')),
('HYD', _('Hydro')),
)),
('PG', _('Power Grids')),
('SM', _('Supply of Minerals')),
)
GENERATION_TYPE_CHOICES = (
('W', 'Wind'),
('S', 'Solar'),
POSITIVE_NEGATIVE_CHOICES = (
('P', _('Positive')),
('N', _('Negative'))
)
LAND_OWNERSHIP_CHOICES = (
('PRI', _('Private Land')),
('PUB', _('Public Land')),
('COM', _('Community Land')),
('OTH', _('Other')),
)
LOCATION_CONTEXT_CHOICES = (
('RUR', _('Rural')),
('URB', _('Urban')),
)
TYPE_OF_ECOSYSTEM_CHOICES = (
(_('Water Based'), (
('MARINE', _('Marine (e.g. Ocean, Sea)')),
('FRESH', _('Freshwater (e.g. Freshwater, Lake)')),
)),
(_('Land Based'), (
('FOREST', _('Forest/Jungle')),
('AGRI', _('Agricultural Land')),
('GRASS', _('Grassland')),
('DESERT', _('Desert (Tundra, Ice or Sand)')),
('WETLND', _('Wetland (Marsh, Mangrove, Peat Soil)')),
('URBAN', _('Urban')),
))
)
PROJECT_STATUS_CHOICES = (
('EXSTNG', _('Existing Project')),
('UCONST', _('Under Construction')),
('PROJCD', _('Projected Project')),
)
##
# Meta Fields
##
# User who submitted case study
author = models.ForeignKey(
User,
@ -25,32 +71,159 @@ class CaseStudy(models.Model):
editable=False
)
project_name = models.CharField(max_length=128)
# Location of map pin
# Date and time of submission
date_created = models.DateTimeField(auto_now=True, null=False)
# Slug derived from entry_name, used in urls for SEO
slug = AutoSlugField(populate_from=['entry_name'])
# 1.1
entry_name = models.CharField(
verbose_name=_("Entry Name"),
help_text=_("Enter the name of the entry. This should usually be the\
name of project."),
max_length=128
)
# N/A - Not explicitly listed in spec
location = models.PointField()
supply_chain = models.CharField(
max_length=1,
choices=SUPPLY_CHAIN_CHOICES
# 1.2
sector_of_economy = models.CharField(
verbose_name=_("Sector of economy"),
help_text=_("Which sector of the renewable energy economy is most\
relevant?"),
max_length=3,
choices=SECTOR_CHOICES
)
generation_type = models.CharField(
# 1.3
positive_or_negative = models.CharField(
verbose_name=_("Positive or negative?"),
help_text=_("Is the case study a positive case or a negative case?"),
max_length=1,
choices=GENERATION_TYPE_CHOICES
choices=POSITIVE_NEGATIVE_CHOICES
)
associated_companies = models.CharField(max_length=128)
financiers = models.CharField(max_length=128)
important_lenders = models.CharField(max_length=128)
# 1.4
country = CountryField()
affects_indigenous = models.BooleanField()
affects_indigenous_reason = models.TextField()
proposed_start = models.DateField()
proposed_completion = models.DateField()
description = models.TextField()
link_to_forum = models.URLField()
image = models.ImageField()
references = models.TextField()
commodities = models.CharField(max_length=128)
like_to_engage_developer = models.BooleanField()
like_to_engage_investors = models.BooleanField()
# 1.5.1
area_of_land = models.IntegerField(
verbose_name=_("Approximate land area"),
help_text=_("The area of land covered by the project (in km²)")
)
# 1.5.2
land_ownership = models.CharField(
verbose_name=_("Land ownership"),
help_text=_("What type of ownership does the land fall under?"),
max_length=3,
choices=LAND_OWNERSHIP_CHOICES
)
# 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
)
# 1.5.4
location_context = models.CharField(
verbose_name=_("Location"),
help_text=_("Select the context that is most applicable to this case\
study."),
max_length=3,
choices=LOCATION_CONTEXT_CHOICES
)
# 1.5.5
type_of_ecosystem = models.CharField(
verbose_name=_("Type of ecosystem"),
help_text=_("Select the most relevant type of ecosystem."),
max_length=6,
choices=TYPE_OF_ECOSYSTEM_CHOICES,
)
# 1.5.5.3
describe_ecosystem = models.CharField(
verbose_name=_("Describe the ecosystem"),
help_text=_("In your own words, add more detail about the ecosystem."),
max_length=256,
)
# 1.5.6
affects_indigenous = models.BooleanField(
verbose_name=_("Affects indigenous people?"),
help_text=_("Does the project affect indigenous people?")
)
# 1.5.6.1
affects_indigenous_detail = models.CharField(
verbose_name=_("Affects Indigenous - Details"),
help_text=_("What group of indigenous people does the community belong\
to?"),
max_length=256
)
# 1.6
project_status = models.CharField(
verbose_name=_("Status of Project"),
help_text=_("What is the status of the current project?"),
max_length=6,
choices=PROJECT_STATUS_CHOICES
)
# 1.9
synopsis = models.TextField(
verbose_name=_("Synopsis"),
help_text=_("Briefly describe the project. This will be displayed at\
the top of the case study page. Maximum 500 chars (about \
3½ tweets)"),
max_length=500
)
# 1.10
full_description = models.TextField(
verbose_name=_("Full Description"),
help_text=_("Describe the project in full. Separate paragraphs with a\
new line Please add as much detail as you feel is necessary\
here.")
)
# 1.15
image = models.ImageField(
verbose_name=_("Image")
)
# 1.16
video = models.URLField(
verbose_name=_("Video"),
max_length=43
)
# 1.18
community_voices = models.TextField(
verbose_name=_("Community Voices"),
help_text=_("Add any direct quotes from members of the community that\
relate to this project")
)
def __str__(self):
return "%s in %s" % (self.project_name, self.country.name)
"""The String representation of the case study. (Entry name with country name.)"""
return "%s in %s" % (self.entry_name, self.country.name)
def clean(self, *args, **kwargs):
"""Perform validation on the model as a whole and throw a ValidationError if anything isn't how it should be."""
pass
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)
# Continue normal save method by calling original save method.
super(CaseStudy, self).save(*args, **kwargs)

4
apps/map/moderator.py Normal file
View File

@ -0,0 +1,4 @@
from moderation import moderation
from apps.map.models import CaseStudy
moderation.register(CaseStudy) # Uses default moderation settings

View File

@ -1,11 +0,0 @@
appdirs==1.4.3
Django==1.11.1
django-countries==4.5
django-crispy-forms==1.6.1
django-leaflet==0.22.0
gunicorn==19.7.1
packaging==16.8
psycopg2==2.7.1
pyparsing==2.2.0
pytz==2017.2
six==1.10.0

17274
apps/map/static/map/bundle.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@ -1,15 +0,0 @@
{% load staticfiles %}
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/"><img src="{% static "map/ojuso-logo-white.png" %}" alt="Ojuso Logo"></a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
{% block nav_links %}
{% endblock %}
</ul>
</div>
</div>
</nav>

View File

@ -1,11 +1,9 @@
{% extends "map/base.html" %}
{% extends "base.html" %}
{% block stylesheets %}
{{ block.super }}
<style>
body {
padding-top: 50px;
}
.page-lead {
padding: 40px 15px;
text-align: center;
@ -15,20 +13,15 @@
{% block body %}
{% include "map/_nav.html" %}
{% block nav_links %}
<li><a href="/case-studies">Case Studies</a></li>
{% endblock %}
<div class="container">
<div class="page-lead">
<h1>{% block title %}{% endblock %}</h1>
<p class="lead">{% block description %}{% endblock %}</p>
<h1 class="text-center">{% block title %}{% endblock %}</h1>
<p class="lead text-center">{% block description %}{% endblock %}</p>
</div>
{% block content %}
{% endblock %}
</div><!-- /.container -->
</div><!-- /.container -->
{% endblock %}

View File

@ -1,13 +1,10 @@
{% extends "map/base.html" %}
{% extends "base.html" %}
{% block stylesheets %}
{{ block.super }}
<style>
body {
padding-top: 50px;
}
.jumbo {
height: calc(100% - 50px);
height: calc(100% - 64px);
width: 100%;
position: absolute;
right: 0;
@ -19,12 +16,10 @@
{% block body %}
{% include "map/_nav.html" %}
<div class="jumbo">
{% block content %}
{% endblock %}
</div><!-- /.container -->
</div><!-- /.container -->
{% endblock %}

View File

@ -0,0 +1,117 @@
{% extends "base_with_jumbo.html" %}
{% load bootstrap3 %}
{% load compress %}
{% load i18n %}
{% load leaflet_tags %}
{% load humanize %}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script src="bundle.js"></script>
</head>
{% block content %}
<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>
<div style="margin-top:70px;padding:0 20px;">
<h1>{{case_study.entry_name}}</h1>
<p>{{case_study.synopsis}}</p>
</div>
<div class="clearfix">
<div style="margin-left:20px;">
<span class="badge badge-pill bg-dark">{{case_study.get_sector_of_economy_display}}</span>
{% if case_study.positive_or_negative == "P" %}
<span class="badge badge-pill bg-success">{{case_study.get_positive_or_negative_display}}</span>
{% elif case_study.positive_or_negative == "N"%}
<span class="badge badge-pill bg-danger">{{case_study.get_positive_or_negative_display}}</span>
{% endif %}
<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>
<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>
</div>
</div>
</div>
<div class="row" style="padding-top:30px;">
<div class="col-lg-8">
<div id="accordion" role="tablist">
<div class="card">
<div class="card-header" role="tab" id="headingOne">
<h5 class="mb-0">
<a data-toggle="collapse" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
{% trans "Full Description" %}
</a>
</h5>
</div>
<div id="collapseOne" class="collapse show" role="tabpanel" aria-labelledby="headingOne" data-parent="#accordion">
<div class="card-body">
{{case_study.full_description}}
</div>
</div>
</div>
<div class="card">
<div class="card-header" role="tab" id="headingTwo">
<h5 class="mb-0">
<a class="collapsed" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
{% trans "Community Voices" %}
</a>
</h5>
</div>
<div id="collapseTwo" class="collapse" role="tabpanel" aria-labelledby="headingTwo" data-parent="#accordion">
<div class="card-body">
{{case_study.community_voices}}
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-header">
{% trans "Factbar" %}
</div>
<div class="card-body">
<ul class="list-group list-group-flush">
{% if case_study.area_of_land %}
<li class="list-group-item">{% trans "Approximate land area"%}: {{case_study.area_of_land}} km²</li>
{% endif %}
</ul>
</div>
</div>
<div class="card">
<div class="card-header">
Attached Files
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<a href="#">File One</a></br>
<small class="text-muted">Uploaded one month ago</small>
</li>
<li class="list-group-item">
<a href="#">File Two</a></br>
<small class="text-muted">Uploaded 3 mins ago</small>
</li>
</ul>
</div>
</div>
</div>
</div>
<footer class="footer text-center">
<div class="container-fluid">
<span class="text-muted">Ojuso x Yansa</span>
</div>
</footer>
{% endblock %}
</html>

View File

@ -1,4 +1,4 @@
{% extends "map/base_with_container.html" %}
{% extends "base_page.html" %}
{% load compress %}
{% load crispy_forms_tags %}
{% load i18n %}
@ -21,4 +21,14 @@
{% block scripts %}
{% leaflet_js %}
<script type="text/javascript">
YourGeometryField = L.GeometryField.extend({
addTo: function (map) {
L.GeometryField.prototype.addTo.call(this, map);
// Customize map for field
console.log(this);
},
// See GeometryField source (static/leaflet/leaflet.forms.js) to override more stuff...
});
</script>
{% endblock %}

View File

@ -0,0 +1,47 @@
{% extends "base_page.html" %}
{% load bootstrap3 %}
{% load compress %}
{% load i18n %}
{% load humanize %}
{% block stylesheets %}
{{ block.super }}
<style>
a.btn-jumbo {
color: navy;
width:320px;
height:240px;
border: 1px solid black;
border-radius: 5px;
white-space: normal;
line-height:55px;
padding:80px 20px;
margin: 20px;
}
a.btn-jumbo > * {
vertical-align: middle;
display: inline-block;
line-height:20px;
}
div.btn-jumbo-group {
text-align: center;
}
</style>
{% endblock %}
{% block title %}{% trans "How much time do you have?" %}{% endblock %}
{% block description %}
{% trans "A complete picture is always more helpful but sometimes you don't have the time" %}
{% endblock %}
{% block content %}
<div class="btn-jumbo-group">
<a class="btn btn-jumbo bg-warning" href="{% url 'long-form' %}" role="button">
<h2>20+ Minutes</h2>
<p>Full Form (Preferred)</p>
</a>
<a class="btn btn-jumbo bg-success" href="{% url 'short-form' %}" role="button">
<h2>5-10 Minutes</h2>
<p>Express Form</p>
</a>
</div>
{% endblock %}

View File

@ -1,6 +1,5 @@
{% extends "map/base_with_jumbo.html" %}
{% extends "base_with_jumbo.html" %}
{% load bootstrap3 %}
{% load compress %}
{% load i18n %}
{% load leaflet_tags %}
@ -46,9 +45,9 @@
onEachFeature: function (feature, layer) {
var modalname = "case-study-"+feature.id
layer.bindPopup(
"<h3>"+feature.properties.project_name+"</h3>"+
"<button type='button' class='btn btn-primary btn-block' data-toggle='modal' data-target='#"+modalname+"'>"
+"{% trans "Quick View" %}"+"</button>"
"<p>"+feature.properties.entry_name+"</p>"+
"<a class='btn btn-primary' href='case-study/"+feature.properties.slug+"' role='button'>"
+"{% trans "View" %}"+"</a>"
);
var modal = create(
"<div class='modal fade' id='"+modalname+"' tabindex='-1' role='dialog' aria-labelledby='"+modalname+"-label'>"+

View File

@ -5,9 +5,10 @@ from .models import CaseStudy
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^data.geojson$',
GeoJSONLayerView.as_view(model=CaseStudy, geometry_field='location'),
name='data'),
url(r'^case-study/add', views.form, name='form')
url(r'^$', views.Map.as_view(), name='index'),
url(r'^data.geojson$', GeoJSONLayerView.as_view(model=CaseStudy, geometry_field='location'), name='data'),
url(r'^case-study/create/?$', views.Create.as_view(), name="create"),
url(r'^case-study/create/short/?$', views.ShortForm.as_view(), name='short-form'),
url(r'^case-study/create/long/?$', views.LongForm.as_view(), name='long-form'),
url(r'^case-study/(?P<slug>[-\w]+)/?$', views.CaseStudyDetail.as_view(), name='detail')
]

View File

@ -1,12 +1,35 @@
from django.shortcuts import render
from .forms import CaseStudyForm
from django.views.generic import DetailView
from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import CaseStudy
from .forms import ShortCaseStudyForm, LongCaseStudyForm
def index(request):
return render(request, 'map/index.html')
class Map(TemplateView):
template_name = "map/index.html"
def form(request):
form = CaseStudyForm
return render(request, 'map/form.html', {'form': form})
class Create(LoginRequiredMixin, TemplateView):
template_name = "map/how_much_time.html"
class BaseForm(LoginRequiredMixin, FormView):
"""This is the base class for the short and long forms. It handles any shared logic between the two subclasses."""
template_name = 'map/form.html'
class ShortForm(BaseForm):
"""Here, we use the short version of the form."""
form_class = ShortCaseStudyForm
class LongForm(BaseForm):
"""Here, we use the long version of the form."""
form_class = LongCaseStudyForm
class CaseStudyDetail(DetailView):
template_name = "map/detail.html"
model = CaseStudy
context_object_name = "case_study"

View File

3
apps/profiles/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
apps/profiles/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class ProfilesConfig(AppConfig):
name = 'profiles'

View File

3
apps/profiles/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

View File

@ -0,0 +1,2 @@
{% extends "base_page.html" %}
Profile page

3
apps/profiles/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

7
apps/profiles/urls.py Normal file
View File

@ -0,0 +1,7 @@
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.Profile.as_view(), name='profile'),
]

5
apps/profiles/views.py Normal file
View File

@ -0,0 +1,5 @@
from django.views.generic.base import TemplateView
class Profile(TemplateView):
template_name = "profiles/profile.html"