Autocomplete from GIS list of CRSs..

..using django-autocomplete-light, in both the admin area and the
end-user form

Closes #32
This commit is contained in:
Carl van Tonder 2018-04-04 15:26:24 -04:00
parent a50c40e739
commit dce53630f7
9 changed files with 101 additions and 17 deletions

View File

@ -1,7 +1,21 @@
from django.contrib import admin from django.contrib import admin
from django import forms
from dal import autocomplete
from leaflet.admin import LeafletGeoAdmin from leaflet.admin import LeafletGeoAdmin
from .models import CaseStudy from .models import CaseStudy, SpatialRefSys
class CaseStudyAdminForm(forms.ModelForm):
class Meta:
model = CaseStudy
widgets = {
'coordinate_reference_system': autocomplete.ModelSelect2(
url='srs-autocomplete'
)
}
fields = '__all__'
class CaseStudyAdmin(LeafletGeoAdmin): class CaseStudyAdmin(LeafletGeoAdmin):
@ -30,4 +44,8 @@ class CaseStudyAdmin(LeafletGeoAdmin):
)) ))
unapprove.short_description = "Un-approve selected case studies" unapprove.short_description = "Un-approve selected case studies"
form = CaseStudyAdminForm
admin.site.register(CaseStudy, CaseStudyAdmin) admin.site.register(CaseStudy, CaseStudyAdmin)
admin.site.register(SpatialRefSys)

View File

@ -2,9 +2,11 @@ from django.urls import reverse
from django import forms from django import forms
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, HTML, Fieldset, Div from crispy_forms.layout import Submit, Layout, HTML, Fieldset, Div
from crispy_forms.bootstrap import Tab, TabHolder, PrependedText, FormActions from crispy_forms.bootstrap import Tab, TabHolder, PrependedText, FormActions
from dal import autocomplete
from leaflet.forms.widgets import LeafletWidget from leaflet.forms.widgets import LeafletWidget
from .models import CaseStudy from .models import CaseStudy
@ -68,6 +70,7 @@ class ShortCaseStudyForm(BaseCaseStudyForm):
'community_voices' 'community_voices'
] ]
class LongCaseStudyForm(BaseCaseStudyForm): class LongCaseStudyForm(BaseCaseStudyForm):
"""Long version of the CaseStudy form.""" """Long version of the CaseStudy form."""
@ -117,6 +120,9 @@ class LongCaseStudyForm(BaseCaseStudyForm):
choices=POSITIVE_CASE_TYPE_CHOICES choices=POSITIVE_CASE_TYPE_CHOICES
) )
self.fields['project_owners'].required = True
self.fields['shareholders'].required = True
self.helper.form_action = reverse('long-form') self.helper.form_action = reverse('long-form')
self.helper.layout = Layout( self.helper.layout = Layout(
TabHolder( TabHolder(
@ -269,3 +275,8 @@ class LongCaseStudyForm(BaseCaseStudyForm):
class Meta(BaseCaseStudyForm.Meta): class Meta(BaseCaseStudyForm.Meta):
exclude = ('approved',) exclude = ('approved',)
widgets = {
'coordinate_reference_system': autocomplete.ModelSelect2(
url='srs-autocomplete'
)
}

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-04-04 00:24
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('map', '0050_auto_20180402_1237'),
]
operations = [
migrations.AlterField(
model_name='casestudy',
name='coordinate_reference_system',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='gis.PostGISSpatialRefSys'),
),
]

View File

@ -1,17 +1,32 @@
import datetime import datetime
from urllib import parse from urllib import parse
from django.contrib.gis.db import models from django.contrib.gis.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django_extensions.db.fields import AutoSlugField from django.db import connection
from django_countries.fields import CountryField
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.template.defaultfilters import slugify from django.template.defaultfilters import slugify
from django_extensions.db.fields import AutoSlugField
from django_countries.fields import CountryField
from multiselectfield import MultiSelectField from multiselectfield import MultiSelectField
from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.modelfields import PhoneNumberField
from . import validators from . import validators
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 Shapefile(models.Model): class Shapefile(models.Model):
file = models.FileField( file = models.FileField(
upload_to='shapefiles/', upload_to='shapefiles/',
@ -1007,13 +1022,9 @@ class CaseStudy(models.Model):
) )
# 4.3.2 # 4.3.2
coordinate_reference_system = models.CharField( coordinate_reference_system = models.ForeignKey(
verbose_name=_("Coordinate reference system"), SpatialRefSys, null=True, blank=True,
help_text=_("Enter the coordinate reference system of the shapefiles."), default=4326
max_length=12,
default=None,
null=True,
blank=True
) )
# 4.3.3 # 4.3.3

View File

@ -1,8 +1,5 @@
{% extends "base_page.html" %} {% extends "base_page.html" %}
{% load compress %} {% load compress crispy_forms_tags i18n leaflet_tags static %}
{% load crispy_forms_tags %}
{% load i18n %}
{% load leaflet_tags %}
{% block stylesheets %} {% block stylesheets %}
@ -20,6 +17,8 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.js' %}"></script>
{{ form.media }}
{% leaflet_js %} {% leaflet_js %}
<script type="text/javascript"> <script type="text/javascript">
YourGeometryField = L.GeometryField.extend({ YourGeometryField = L.GeometryField.extend({

View File

@ -8,11 +8,15 @@ from . import views
urlpatterns = [ urlpatterns = [
url(r'^$', RedirectView.as_view(url=reverse_lazy('map')), name='index'), url(r'^$', RedirectView.as_view(url=reverse_lazy('map')), 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/?$', views.Create.as_view(), name="create"),
url(r'^case-study/create/short/?$', views.ShortForm.as_view(), name='short-form'), 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/create/long/?$', views.LongForm.as_view(), name='long-form'),
url(r'^case-study/create/success/?$', views.FormSuccess.as_view(), name='form-success'), url(r'^case-study/create/success/?$', views.FormSuccess.as_view(), name='form-success'),
url(r'^case-study/(?P<slug>[-\w]+)/?$', views.CaseStudyDetail.as_view(), name='detail'), url(r'^case-study/(?P<slug>[-\w]+)/?$', views.CaseStudyDetail.as_view(), name='detail'),
url(r'^map/?$', views.Map.as_view(), name='map') url(r'^map/?$', views.Map.as_view(), name='map'),
# API
url(r'^data.geojson$', GeoJSONLayerView.as_view(model=CaseStudy, geometry_field='location'), name='data'),
url(r'^srs-autocomplete/$', views.SpatialRefSysAutocomplete.as_view(), name='srs-autocomplete'),
] ]

View File

@ -1,11 +1,15 @@
from django.core.mail import send_mail from django.core.mail import send_mail
from django.conf import settings from django.conf import settings
from django.db.models import Q
from django.views.generic import DetailView from django.views.generic import DetailView
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django.views.generic.edit import CreateView from django.views.generic.edit import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse from django.urls import reverse
from .models import CaseStudy
from dal import autocomplete
from .models import CaseStudy, SpatialRefSys
from .forms import ShortCaseStudyForm, LongCaseStudyForm from .forms import ShortCaseStudyForm, LongCaseStudyForm
NOTIFY_MESSAGE = """ NOTIFY_MESSAGE = """
@ -72,3 +76,16 @@ class CaseStudyDetail(DetailView):
template_name = "map/detail.html" template_name = "map/detail.html"
model = CaseStudy model = CaseStudy
context_object_name = "case_study" context_object_name = "case_study"
class SpatialRefSysAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
qs = SpatialRefSys.objects.all()
if self.q:
qs = qs.filter(
Q(auth_name__icontains=self.q)
| Q(auth_srid__icontains=self.q)
)
return qs

View File

@ -47,6 +47,8 @@ INSTALLED_APPS = [
'cas_server', 'cas_server',
'compressor', 'compressor',
'crispy_forms', 'crispy_forms',
'dal',
'dal_select2',
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',

View File

@ -5,6 +5,7 @@ boto3==1.4.7
Django==1.11.6 Django==1.11.6
django-appconf==1.0.2 django-appconf==1.0.2
django-anymail==2.0 django-anymail==2.0
django-autocomplete-light==3.2.10
django-avatar==4.0.1 django-avatar==4.0.1
django-bootstrap3==8.2.3 django-bootstrap3==8.2.3
django-braces==1.11.0 django-braces==1.11.0