26 changed files with 0 additions and 1231 deletions
-
49abonapp/tests.py
-
16accounts_app/tests.py
-
3chatbot/tests.py
-
1clientsideapp/tests.py
-
43gmap/admin.py
-
20gmap/forms.py
-
114gmap/migrations/0001_initial.py
-
369gmap/models.py
-
1gmap/tests.py
-
16gmap/urls.py
-
143gmap/utils.py
-
250gmap/views.py
-
1ip_pool/tests.py
-
3mapapp/tests.py
-
16photo_app/tests.py
-
22privatemessage/tests.py
-
1searchapp/tests.py
-
4static/css/gmap.css
-
BINstatic/img/0ZKOa52wPuc.jpg
-
BINstatic/img/kpkLhcH5R4E.jpg
-
1statistics/tests.py
-
1tariff_app/tests.py
-
1taskapp/tests.py
-
135templates/maps/gmap.html
-
15templates/maps/gmap_import_errors.html
-
6templates/maps/gmap_search.html
@ -1,49 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from django.shortcuts import get_object_or_404 |
|||
from django.test import TestCase |
|||
|
|||
from .models import Abon, AbonTariff |
|||
from tariff_app.models import Tariff |
|||
|
|||
|
|||
class AbonTariffTestCase(TestCase): |
|||
def setUp(self): |
|||
abon1 = Abon.objects.create( |
|||
telephone='+79784653751', |
|||
fio='ФИО абона', |
|||
username='аго мучич' |
|||
) |
|||
tarif1 = Tariff.objects.create( |
|||
title='Тариф 1', |
|||
speedIn=120.3, |
|||
speedOut=53, |
|||
amount=38 |
|||
) |
|||
tarif2 = Tariff.objects.create( |
|||
title='Тариф 2', |
|||
speedIn=130.3, |
|||
speedOut=23, |
|||
amount=82 |
|||
) |
|||
AbonTariff.objects.create( |
|||
abon=abon1, |
|||
tariff=tarif1, |
|||
tariff_priority=0 |
|||
) |
|||
AbonTariff.objects.create( |
|||
abon=abon1, |
|||
tariff=tarif2, |
|||
tariff_priority=1 |
|||
) |
|||
|
|||
def test_activate_next(self): |
|||
# возьмём абонента для опытов |
|||
abn = get_object_or_404(Abon, username='аго мучич') |
|||
|
|||
# берём купленные услуги |
|||
ats = AbonTariff.objects.filter(abon=abn) |
|||
for at in ats: |
|||
# и пробуем назначить |
|||
at.activate_next_tariff() |
|||
|
|||
AbonTariff.objects.update_priorities(ats) |
|||
@ -1,16 +0,0 @@ |
|||
""" |
|||
This file demonstrates writing tests using the unittest module. These will pass |
|||
when you run "manage.py test". |
|||
|
|||
Replace this with more appropriate tests for your application. |
|||
""" |
|||
|
|||
from django.test import TestCase |
|||
|
|||
|
|||
class SimpleTest(TestCase): |
|||
def test_basic_addition(self): |
|||
""" |
|||
Tests that 1 + 1 always equals 2. |
|||
""" |
|||
self.assertEqual(1 + 1, 2) |
|||
@ -1,3 +0,0 @@ |
|||
from django.test import TestCase |
|||
|
|||
# Create your tests here. |
|||
@ -1 +0,0 @@ |
|||
# Create your tests here. |
|||
@ -1,43 +0,0 @@ |
|||
from django.contrib import admin |
|||
|
|||
from gmap.models import MapMarker, MarkerCategory, MarkerSubCategory, SalesDirector, SalesBoundary, CountryISOCode |
|||
|
|||
|
|||
class MarkerAdmin(admin.ModelAdmin): |
|||
list_display = [ |
|||
'name', |
|||
'contact_title', |
|||
'category', |
|||
'contact_name', |
|||
'airport_code', |
|||
'address', |
|||
'platinum', |
|||
'airport_name', |
|||
'phone', |
|||
'fax', |
|||
'email', |
|||
'url' |
|||
] |
|||
exclude = ('latitude', 'longitude') |
|||
|
|||
|
|||
class MarkerInline(admin.TabularInline): |
|||
model = MapMarker |
|||
exclude = ('latitude', 'longitude') |
|||
extra = 1 |
|||
|
|||
|
|||
class BoundaryAdmin(admin.ModelAdmin): |
|||
list_display = ['boundary_code', 'owner'] |
|||
|
|||
|
|||
class DirectorAdmin(admin.ModelAdmin): |
|||
list_display = ['name', 'country'] |
|||
|
|||
|
|||
admin.site.register(MapMarker, MarkerAdmin) |
|||
admin.site.register(MarkerCategory) |
|||
admin.site.register(MarkerSubCategory) |
|||
admin.site.register(CountryISOCode) |
|||
admin.site.register(SalesDirector, DirectorAdmin) |
|||
admin.site.register(SalesBoundary, BoundaryAdmin) |
|||
@ -1,20 +0,0 @@ |
|||
from django import forms |
|||
|
|||
from gmap.models import MapMarker, CountryISOCode |
|||
|
|||
|
|||
class ModifiedChoiceField(forms.ModelChoiceField): |
|||
def label_from_instance(self, obj): |
|||
if 'long_name' in obj: |
|||
return obj['long_name'] |
|||
|
|||
if 'state' in obj: |
|||
return obj['state'] |
|||
|
|||
return 'No Data' |
|||
|
|||
|
|||
class MapSearchForm(forms.Form): |
|||
state = ModifiedChoiceField( |
|||
queryset=MapMarker.objects.filter(country__iso_3='USA').values('state').order_by('state').distinct(), label='') |
|||
country = ModifiedChoiceField(queryset=CountryISOCode.objects.order_by('long_name').values('long_name'), label='') |
|||
@ -1,114 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.9 on 2016-11-30 15:15 |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
initial = True |
|||
|
|||
dependencies = [ |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='CountryISOCode', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('long_name', models.CharField(max_length=200)), |
|||
('iso_3', models.CharField(blank=True, max_length=10)), |
|||
('iso_2', models.CharField(blank=True, max_length=10)), |
|||
], |
|||
), |
|||
migrations.CreateModel( |
|||
name='MapMarker', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('name', models.CharField(max_length=200)), |
|||
('latitude', models.CharField(blank=True, max_length=30)), |
|||
('longitude', models.CharField(blank=True, max_length=30)), |
|||
('platinum', models.BooleanField(default=False, verbose_name='Platinum Partner')), |
|||
('contact_name', models.CharField(blank=True, max_length=50)), |
|||
('contact_title', models.CharField(blank=True, max_length=50)), |
|||
('airport_name', models.CharField(blank=True, max_length=100)), |
|||
('airport_code', models.CharField(blank=True, max_length=6)), |
|||
('address', models.TextField(blank=True, max_length=200)), |
|||
('city', models.CharField(blank=True, max_length=200)), |
|||
('state', models.CharField(blank=True, max_length=50)), |
|||
('zipcode', models.CharField(blank=True, max_length=10)), |
|||
('phone', models.CharField(blank=True, max_length=40)), |
|||
('fax', models.CharField(blank=True, max_length=40)), |
|||
('email', models.EmailField(blank=True, max_length=254)), |
|||
('url', models.URLField(blank=True)), |
|||
], |
|||
), |
|||
migrations.CreateModel( |
|||
name='MarkerCategory', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('name', models.CharField(max_length=200, unique=True, verbose_name='type')), |
|||
('position', models.IntegerField(default=0)), |
|||
('icon', models.ImageField(blank=True, upload_to='gmap-icons/', verbose_name='icon')), |
|||
('platinum_icon', models.ImageField(blank=True, upload_to='gmap-icons/', verbose_name='platinum icon')), |
|||
('shadow', models.ImageField(blank=True, upload_to='gmap-icons/', verbose_name='icon shadow')), |
|||
], |
|||
), |
|||
migrations.CreateModel( |
|||
name='MarkerSubCategory', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('name', models.CharField(max_length=200, unique=True, verbose_name='Name')), |
|||
], |
|||
), |
|||
migrations.CreateModel( |
|||
name='SalesBoundary', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('boundary_code', models.CharField(max_length=75, verbose_name='Boundary Code')), |
|||
], |
|||
), |
|||
migrations.CreateModel( |
|||
name='SalesDirector', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('name', models.CharField(max_length=100, unique=True, verbose_name='Name')), |
|||
('title', models.CharField(blank=True, max_length=50)), |
|||
('phone', models.CharField(blank=True, max_length=40, verbose_name='Phone Number')), |
|||
('email', models.EmailField(blank=True, max_length=254, verbose_name='Email')), |
|||
('airport_code', models.CharField(blank=True, max_length=8)), |
|||
('airport_name', models.CharField(blank=True, max_length=50)), |
|||
('address', models.TextField(blank=True, max_length=200)), |
|||
('city', models.CharField(blank=True, max_length=200)), |
|||
('state', models.CharField(blank=True, max_length=100)), |
|||
('zipcode', models.CharField(blank=True, max_length=10)), |
|||
('url', models.URLField(blank=True)), |
|||
('country', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='gmap.CountryISOCode')), |
|||
], |
|||
), |
|||
migrations.AddField( |
|||
model_name='salesboundary', |
|||
name='owner', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gmap.SalesDirector'), |
|||
), |
|||
migrations.AddField( |
|||
model_name='mapmarker', |
|||
name='category', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gmap.MarkerCategory'), |
|||
), |
|||
migrations.AddField( |
|||
model_name='mapmarker', |
|||
name='country', |
|||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='gmap.CountryISOCode'), |
|||
), |
|||
migrations.AddField( |
|||
model_name='mapmarker', |
|||
name='sub_categories', |
|||
field=models.ManyToManyField(related_name='sub_categories', to='gmap.MarkerSubCategory'), |
|||
), |
|||
migrations.AlterUniqueTogether( |
|||
name='salesboundary', |
|||
unique_together={('boundary_code', 'owner')}, |
|||
), |
|||
] |
|||
@ -1,369 +0,0 @@ |
|||
from django.db import models |
|||
|
|||
from gmap.utils import geolocate |
|||
|
|||
|
|||
CATEGORY_LOOKUP = {'1': 'Cirrus Authorized Service Center (ASC)', '2': 'Cirrus Sales Representative or Center', |
|||
'3': 'Cirrus Training Center (CTC)', '4': 'Cirrus Standardized Instructor Pilot (CSIP)'} |
|||
|
|||
INVERSE_CATEGORY = dict((v, k) for k, v in CATEGORY_LOOKUP.items()) |
|||
|
|||
SUBCATEGORY_LOOKUP = { |
|||
|
|||
'1': 'Composite & Paint Repair', |
|||
'2': 'Pickup & Delivery Service', |
|||
'3': 'Parts Distributor', |
|||
'4': 'Air Conditioning Service', |
|||
'5': 'Garmin Service', |
|||
'6': 'Avidyne Service', |
|||
'7': 'Full Avionics Facility', |
|||
'8': 'Oxygen Service', |
|||
'9': 'Wi-Fi Equipped', |
|||
'10': 'CAPS Overhaul', |
|||
'11': 'Cirrus Platinum Service Partner', |
|||
'12': 'Ice Protection System Maintenance', |
|||
'13': 'SR20 Rental', |
|||
'14': 'SR22 Rental', |
|||
'15': 'SR22T Rental', |
|||
'16': 'Cirrus Perspective Avionics Available', |
|||
'17': 'Avidyne Entegra Avionics Available', |
|||
'18': 'Cirrus Platinum Training Partner', |
|||
'19': 'Simulator Available', |
|||
'20': 'Cirrus Perspective Qualified', |
|||
'21': 'Avidyne Entegra Qualified', |
|||
'22': 'New Cirrus Sales', |
|||
'23': 'Used Cirrus Sales', |
|||
'24': 'n/a' |
|||
|
|||
} |
|||
|
|||
INVERSE_SUBCATEGORY = dict((v, k) for k, v in SUBCATEGORY_LOOKUP.items()) |
|||
|
|||
# name, category, platinum partner, contacT_name, contact_title, airport_name, airport_code, address, phone, fax, email, url, sub_category1, ..., sub_categoryN |
|||
|
|||
SUBCAT_IDX = 18 |
|||
# SUBCAT_IDX = 12 |
|||
|
|||
# NAME_COLUMN = 2 |
|||
NAME_COLUMN = 0 |
|||
#CATEGORY_COLUMN = 3 |
|||
CATEGORY_COLUMN = 1 |
|||
#ADDRESS_COLUMN = 9 |
|||
ADDRESS_COLUMN = 7 |
|||
SUBCATEGORY_COLUMN = SUBCAT_IDX |
|||
|
|||
|
|||
class SalesBoundary(models.Model): |
|||
boundary_code = models.CharField('Boundary Code', max_length=75) |
|||
owner = models.ForeignKey('SalesDirector'); |
|||
|
|||
class Meta: |
|||
unique_together = ("boundary_code", "owner") |
|||
|
|||
def __str__(self): |
|||
return self.boundary_code |
|||
|
|||
|
|||
class SalesDirector(models.Model): |
|||
name = models.CharField('Name', max_length=100, unique=True) |
|||
title = models.CharField(max_length=50, blank=True) |
|||
phone = models.CharField('Phone Number', max_length=40, blank=True) |
|||
email = models.EmailField('Email', blank=True) |
|||
airport_code = models.CharField(max_length=8, blank=True) |
|||
airport_name = models.CharField(max_length=50, blank=True) |
|||
address = models.TextField(max_length=200, blank=True) |
|||
city = models.CharField(max_length=200, blank=True) |
|||
state = models.CharField(max_length=100, blank=True) |
|||
zipcode = models.CharField(max_length=10, blank=True) |
|||
url = models.URLField(blank=True) |
|||
country = models.ForeignKey('CountryISOCode', blank=True) |
|||
|
|||
def from_csv(self, row, row_id, errors): |
|||
|
|||
local_errors = False |
|||
|
|||
''' |
|||
self.name, cat, plat, self.contact_name, self.contact_title = row[0:5] |
|||
self.airport_name, self.airport_code, self.address, self.phone, self.fax = row[5:10] |
|||
self.email, self.url = row[10:12] |
|||
|
|||
subcategories = row[12:] |
|||
''' |
|||
|
|||
cat, plat = '', '' |
|||
subcategories = [] |
|||
|
|||
try: |
|||
|
|||
self.name, cat, plat, self.contact_name, self.title = row[0:5] |
|||
self.airport_name, self.airport_code, self.address, self.phone, fax = row[5:10] |
|||
self.email, self.url, self.state, iso_3, self.city, self.zipcode, latitude, longitude = row[10:SUBCAT_IDX] |
|||
|
|||
subcat_string = row[SUBCAT_IDX] |
|||
|
|||
if ',' in subcat_string: |
|||
subcategories = subcat_string.split(',') |
|||
|
|||
else: |
|||
subcategories = [subcat_string] |
|||
|
|||
except IndexError: |
|||
error_string = "Entry does not contain required number of fields: %s < %s" % (len(row), SUBCAT_IDX) |
|||
errors.append(('%s : %s' % (row_id, error_string))) |
|||
return |
|||
|
|||
except ValueError: |
|||
error_string = "Entry does not contain required number of fields: %s < %s" % (len(row), SUBCAT_IDX) |
|||
errors.append(('%s : %s' % (row_id, error_string))) |
|||
return |
|||
|
|||
if not self.name: |
|||
local_errors = True |
|||
row[NAME_COLUMN] = '<font color="red">INSERT_NAME</font>' |
|||
|
|||
if local_errors: |
|||
error_string = ', '.join(row) |
|||
errors.append(('%s : %s' % (row_id, error_string))) |
|||
return |
|||
|
|||
try: |
|||
self.country = CountryISOCode.objects.get(long_name=iso_3) |
|||
|
|||
except: |
|||
|
|||
try: |
|||
self.country = CountryISOCode.objects.get(iso_3=iso_3) |
|||
|
|||
except: |
|||
|
|||
try: |
|||
self.country = CountryISOCode.objects.get(iso_2=iso_3) |
|||
|
|||
except: |
|||
error_string = "Unable to map %s to ISO long name, two letter abbreviation, or three letter abbreviation" % iso_3 |
|||
errors.append(('%s : %s' % (row_id, error_string))) |
|||
|
|||
# Ask django really, really nicely not to insert our object twice |
|||
self.save() |
|||
|
|||
def __str__(self): |
|||
return self.name |
|||
|
|||
|
|||
class MarkerCategoryManager(models.Manager): |
|||
def get_by_natural_key(self, name): |
|||
return self.get(name=name) |
|||
|
|||
|
|||
class MarkerCategory(models.Model): |
|||
objects = MarkerCategoryManager() |
|||
name = models.CharField('type', max_length=200, unique=True) |
|||
position = models.IntegerField(default=0); |
|||
icon = models.ImageField('icon', blank=True, upload_to='gmap-icons/') |
|||
platinum_icon = models.ImageField('platinum icon', blank=True, upload_to='gmap-icons/') |
|||
shadow = models.ImageField('icon shadow', blank=True, upload_to='gmap-icons/') |
|||
|
|||
def natural_key(self): |
|||
return self.name |
|||
|
|||
def __str__(self): |
|||
return self.name |
|||
|
|||
|
|||
class MarkerSubCategory(models.Model): |
|||
objects = MarkerCategoryManager() |
|||
name = models.CharField('Name', max_length=200, unique=True) |
|||
|
|||
def natural_key(self): |
|||
return self.name |
|||
|
|||
def __str__(self): |
|||
return self.name |
|||
|
|||
|
|||
class GeolocateFailure(Exception): |
|||
def __init__(self, message, address): |
|||
self.message = message |
|||
self.address = address |
|||
|
|||
def __str__(self): |
|||
return '%s - %s' % (self.message, self.address) |
|||
|
|||
|
|||
class CountryISOCode(models.Model): |
|||
long_name = models.CharField(max_length=200) |
|||
iso_3 = models.CharField(max_length=10, blank=True) |
|||
iso_2 = models.CharField(max_length=10, blank=True) |
|||
|
|||
def natural_key(self): |
|||
return self.long_name |
|||
|
|||
def __str__(self): |
|||
return self.long_name |
|||
|
|||
|
|||
class MapMarker(models.Model): |
|||
name = models.CharField(max_length=200) |
|||
latitude = models.CharField(max_length=30, blank=True) |
|||
longitude = models.CharField(max_length=30, blank=True) |
|||
category = models.ForeignKey('MarkerCategory') |
|||
platinum = models.BooleanField('Platinum Partner', default=False) |
|||
sub_categories = models.ManyToManyField(MarkerSubCategory, related_name='sub_categories') |
|||
contact_name = models.CharField(max_length=50, blank=True) |
|||
contact_title = models.CharField(max_length=50, blank=True) |
|||
airport_name = models.CharField(max_length=100, blank=True) |
|||
airport_code = models.CharField(max_length=6, blank=True) |
|||
address = models.TextField(max_length=200, blank=True) |
|||
city = models.CharField(max_length=200, blank=True) |
|||
state = models.CharField(max_length=50, blank=True) |
|||
zipcode = models.CharField(max_length=10, blank=True) |
|||
country = models.ForeignKey('CountryISOCode', null=True, blank=True) |
|||
phone = models.CharField(max_length=40, blank=True) |
|||
fax = models.CharField(max_length=40, blank=True) |
|||
email = models.EmailField(blank=True) |
|||
url = models.URLField(blank=True) |
|||
|
|||
# Make sure we update the lat/long with the location |
|||
def save(self, *args, **kwargs): |
|||
|
|||
if not self.latitude and not self.longitude: |
|||
full_address = "%s, %s, %s, %s, %s" % (self.address, self.city, self.state, self.zipcode, self.country) |
|||
latlng = geolocate(repr(full_address)) |
|||
|
|||
if latlng != None: |
|||
self.latitude = latlng['latitude'] |
|||
self.longitude = latlng['longitude'] |
|||
|
|||
else: |
|||
raise GeolocateFailure("Failed to geolocate address for %s" % self.name, full_address) |
|||
|
|||
super().save(*args, **kwargs) |
|||
|
|||
def __str__(self): |
|||
return self.name |
|||
|
|||
def from_csv(self, row, row_id, errors): |
|||
|
|||
local_errors = False |
|||
|
|||
''' |
|||
self.name, cat, plat, self.contact_name, self.contact_title = row[0:5] |
|||
self.airport_name, self.airport_code, self.address, self.phone, self.fax = row[5:10] |
|||
self.email, self.url = row[10:12] |
|||
|
|||
subcategories = row[12:] |
|||
''' |
|||
|
|||
cat, plat = '', '' |
|||
subcategories = [] |
|||
|
|||
try: |
|||
|
|||
self.name, cat, plat, self.contact_name, self.contact_title = row[0:5] |
|||
self.airport_name, self.airport_code, self.address, self.phone, self.fax = row[5:10] |
|||
self.email, self.url, self.state, iso_3, self.city, self.zipcode, self.latitude, self.longitude = row[ |
|||
10:SUBCAT_IDX] |
|||
|
|||
subcat_string = row[SUBCAT_IDX] |
|||
|
|||
if ',' in subcat_string: |
|||
subcategories = subcat_string.split(',') |
|||
|
|||
else: |
|||
subcategories = [subcat_string] |
|||
|
|||
except IndexError: |
|||
error_string = "Entry does not contain required number of fields: %s < %s" % (len(row), SUBCAT_IDX) |
|||
errors.append(('%s : %s' % (row_id, error_string))) |
|||
return |
|||
|
|||
except ValueError: |
|||
error_string = "Entry does not contain required number of fields: %s < %s" % (len(row), SUBCAT_IDX) |
|||
errors.append(('%s : %s' % (row_id, error_string))) |
|||
return |
|||
|
|||
if not self.name: |
|||
local_errors = True |
|||
row[NAME_COLUMN] = '<font color="red">INSERT_NAME</font>' |
|||
|
|||
if not cat: |
|||
local_errors = True |
|||
row[CATEGORY_COLUMN] = '<font color="red">INSERT_CATEGORY</font>' |
|||
|
|||
#if not self.address: |
|||
# local_errors = True |
|||
# row[ADDRESS_COLUMN] = '<font color="red">INSERT_ADDRESS</font>' |
|||
|
|||
if not len(subcategories): |
|||
local_errors = True |
|||
row.append('<font color="red">INSERT_SUBCATEGORY</font>') |
|||
|
|||
elif not subcategories[0]: |
|||
local_errors = True |
|||
row[SUBCATEGORY_COLUMN] = '<font color="red">INSERT_SUBCATEGORY</font>' |
|||
|
|||
if local_errors: |
|||
error_string = ', '.join(row) |
|||
errors.append(('%s : %s' % (row_id, error_string))) |
|||
return |
|||
|
|||
self.platinum = True if plat == '1' else False |
|||
|
|||
self.category = MarkerCategory.objects.get(pk=cat.strip().strip("'")) |
|||
|
|||
try: |
|||
self.country = CountryISOCode.objects.get(long_name=iso_3) |
|||
|
|||
except: |
|||
|
|||
try: |
|||
self.country = CountryISOCode.objects.get(iso_3=iso_3) |
|||
|
|||
except: |
|||
|
|||
try: |
|||
self.country = CountryISOCode.objects.get(iso_2=iso_3) |
|||
|
|||
except: |
|||
error_string = "Unable to map %s to ISO long name, two letter abbreviation, or three letter abbreviation" % iso_3 |
|||
errors.append(('%s : %s' % (row_id, error_string))) |
|||
|
|||
# object's gotta be in the DB before it can get M2M mapping... |
|||
# |
|||
try: |
|||
self.save() |
|||
|
|||
except GeolocateFailure as inst: |
|||
errors.append('%s : %s' % (row_id, inst)) |
|||
return |
|||
|
|||
# ...like this one! |
|||
for subcategory in subcategories: |
|||
if subcategory: |
|||
self.sub_categories.add(MarkerSubCategory.objects.get(pk=subcategory.strip().strip("'"))) |
|||
|
|||
|
|||
# Ask django really, really nicely not to insert our object twice |
|||
self.save(force_update=True) |
|||
|
|||
# Expected csv format: |
|||
# |
|||
# name, category, platinum partner, contacT_name, contact_title, airport_name, airport_code, address, phone, fax, email, url, sub_category1, ..., sub_categoryN |
|||
# |
|||
def csv_row(self): |
|||
|
|||
# my baseline doesn't have: plat partner, contact_name, contact_title, airport_name, |
|||
# TODO: now it does! |
|||
|
|||
''' |
|||
return [self.latitude, self.longitude, self.name, INVERSE_CATEGORY[self.category.name], str(self.platinum), self.contact_name, self.contact_title, |
|||
self.airport_name, self.airport_code, self.address, self.phone, self.fax, |
|||
self.email, self.url] + [INVERSE_SUBCATEGORY[subcat.name] for subcat in self.sub_categories.all()] |
|||
''' |
|||
|
|||
return [self.name, INVERSE_CATEGORY[self.category.name], str(self.platinum), self.contact_name, |
|||
self.contact_title, |
|||
self.airport_name, self.airport_code, self.address, self.phone, self.fax, |
|||
self.email, self.url] + [INVERSE_SUBCATEGORY[subcat.name] for subcat in self.sub_categories.all()] |
|||
|
|||
|
|||
@ -1 +0,0 @@ |
|||
# Create your tests here. |
|||
@ -1,16 +0,0 @@ |
|||
from django.conf.urls import url |
|||
|
|||
from gmap.views import index, showmap, markers, gmap_search, categories, dump_csv, director_by_boundary, director_import |
|||
|
|||
|
|||
app_name = 'gmap' |
|||
urlpatterns = [ |
|||
url(r'^$', index, name="index"), |
|||
url(r'^markers.json$', markers, name="markers"), |
|||
url(r'^categories.json$', categories, name="categories"), |
|||
url(r'^directors/(?P<boundary_code>.+)/$', director_by_boundary, name="directors"), |
|||
url(r'^boundary_import/$', director_import, name="boundary_import"), |
|||
url(r'^search/?', gmap_search, name="gmap_search"), |
|||
url(r'^(?P<address>\w+)$', showmap, name="show_map"), |
|||
url(r'^csv/?', dump_csv, name="dump_csv"), |
|||
] |
|||
@ -1,143 +0,0 @@ |
|||
import json |
|||
import urllib.request, urllib.parse, urllib.error |
|||
import urllib.request, urllib.error, urllib.parse |
|||
import csv |
|||
import codecs |
|||
import io |
|||
|
|||
|
|||
def csvByLine(csvFile, lineHandler): |
|||
errors = '' |
|||
for row_id, line in enumerate(UnicodeReader(csvFile)): |
|||
print(("Calling Line handler for %s" % line)) |
|||
errors = ''.join([errors, lineHandler(line)]) |
|||
return errors |
|||
|
|||
|
|||
def geolocate(location, sensor=False): |
|||
""" |
|||
Take a "location" and return its latitude and longitude |
|||
|
|||
Keyword arguments: |
|||
location - String defining a geographical location (address, zip code, etc) |
|||
sensor - Boolean defining whether the location was taken from |
|||
an on-device sensor |
|||
|
|||
Output: |
|||
latitude and logitude in an dict |
|||
""" |
|||
sensor = str(sensor).lower() |
|||
url = "http://maps.googleapis.com/maps/api/geocode/json?" |
|||
url += urllib.parse.urlencode({'address': location, 'sensor': sensor}) |
|||
data = urllib.request.urlopen(url).read() |
|||
data = json.loads(data) |
|||
if data and data['status'] == 'OK': |
|||
return ({ |
|||
'latitude': data['results'][0]['geometry']['location']['lat'], |
|||
'longitude': data['results'][0]['geometry']['location']['lng'] |
|||
}) |
|||
else: |
|||
return None |
|||
|
|||
|
|||
def georeverse(lat, lon): |
|||
# construct url for reverse geocoding with google-maps |
|||
url = "http://maps.googleapis.com/maps/api/geocode/json?" |
|||
url += urllib.parse.urlencode({'latlng': lat + ',' + lon, 'sensor': 'false'}) |
|||
|
|||
# retrieve and load google-map data |
|||
data = urllib.request.urlopen(url).read() |
|||
data = json.loads(data) |
|||
|
|||
# if request goes through, return the state and country of the location |
|||
if data['status'] == 'OK': |
|||
address_components = data['results'][0]['address_components'] |
|||
|
|||
# these probably shouldn't be booleans (test with None data-type at some point) |
|||
country = False |
|||
state = False |
|||
|
|||
for component in address_components: |
|||
|
|||
try: |
|||
if component['types'][0] == 'country': |
|||
country = component['long_name'] |
|||
|
|||
if component['types'][0] == 'administrative_area_level_1': |
|||
state = component['long_name'] |
|||
except Exception: |
|||
pass |
|||
|
|||
return ({ |
|||
'state': state, |
|||
'country': country |
|||
}) |
|||
return ({ |
|||
'state': False, |
|||
'country': False |
|||
}) |
|||
|
|||
|
|||
class UTF8Recoder: |
|||
""" |
|||
Iterator that reads an encoded stream and reencodes the input to UTF-8 |
|||
""" |
|||
|
|||
def __init__(self, f, encoding): |
|||
self.reader = codecs.getreader(encoding)(f) |
|||
|
|||
def __iter__(self): |
|||
return self |
|||
|
|||
def __next__(self): |
|||
# return self.reader.next().decode("cp1252").encode("utf-8") |
|||
return self.reader.next().encode("utf-8") |
|||
|
|||
|
|||
class UnicodeReader: |
|||
""" |
|||
A CSV reader which will iterate over lines in the CSV file "f", |
|||
which is encoded in the given encoding. |
|||
""" |
|||
|
|||
# def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): |
|||
def __init__(self, f, dialect=csv.excel, encoding="cp1252", **kwds): |
|||
f = UTF8Recoder(f, encoding) |
|||
self.reader = csv.reader(f, dialect=dialect, **kwds) |
|||
|
|||
def __next__(self): |
|||
row = next(self.reader) |
|||
return [str(s, "utf-8") for s in row] |
|||
|
|||
def __iter__(self): |
|||
return self |
|||
|
|||
|
|||
class UnicodeWriter: |
|||
""" |
|||
A CSV writer which will write rows to CSV file "f", |
|||
which is encoded in the given encoding. |
|||
""" |
|||
|
|||
def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): |
|||
# Redirect output to a queue |
|||
self.queue = io.StringIO() |
|||
self.writer = csv.writer(self.queue, dialect=dialect, **kwds) |
|||
self.stream = f |
|||
self.encoder = codecs.getincrementalencoder(encoding)() |
|||
|
|||
def writerow(self, row): |
|||
self.writer.writerow([s.encode("utf-8") for s in row]) |
|||
# Fetch UTF-8 output from the queue ... |
|||
data = self.queue.getvalue() |
|||
data = data.decode("utf-8") |
|||
# ... and reencode it into the target encoding |
|||
data = self.encoder.encode(data) |
|||
# write to the target stream |
|||
self.stream.write(data) |
|||
# empty queue |
|||
self.queue.truncate(0) |
|||
|
|||
def writerows(self, rows): |
|||
for row in rows: |
|||
self.writerow(row) |
|||
@ -1,250 +0,0 @@ |
|||
import csv |
|||
import tempfile |
|||
import time |
|||
|
|||
from django.conf import settings |
|||
from django.core import serializers |
|||
from django.http import HttpResponse, HttpResponseRedirect |
|||
from django.shortcuts import render, render_to_response |
|||
|
|||
from gmap.utils import geolocate, georeverse, csvByLine |
|||
from gmap.models import MapMarker, MarkerCategory, SalesDirector, SalesBoundary |
|||
from gmap.forms import MapSearchForm |
|||
import gmap.utils |
|||
|
|||
|
|||
def index(request): |
|||
form = MapSearchForm() |
|||
response = render(request, 'maps/gmap.html', {'form': form}) |
|||
response['Cache-Control'] = 'no-cache' |
|||
return response |
|||
|
|||
|
|||
def newsales(args): |
|||
try: |
|||
director_name, code = tuple(args) |
|||
except: |
|||
err = open("Errors.log", "a") |
|||
err_text = "Issues getting tuple from: %s\n" % args |
|||
err.write(err_text) |
|||
err.close() |
|||
return err_text |
|||
|
|||
director, new_director = SalesDirector.objects.get_or_create(name=director_name) |
|||
boundary, created = SalesBoundary.objects.get_or_create(boundary_code=code, owner=director) |
|||
|
|||
if (new_director): |
|||
err = open("Errors.log", "a") |
|||
err_text = "We had to make a new director named: %s\n" % director_name |
|||
err.write(err_text) |
|||
err.close() |
|||
return err_text |
|||
return "" |
|||
|
|||
|
|||
def director_import(request): |
|||
errors = csvByLine(request.FILES['datafile'], newsales) |
|||
return HttpResponse(errors.replace('\n', '<br />')) |
|||
|
|||
|
|||
def showmap(request, address='', category=''): |
|||
context = {} |
|||
context['media_url'] = settings.MEDIA_URL |
|||
|
|||
if request.method == 'POST': |
|||
address = request.POST.get('address', address) |
|||
category = request.POST.get('category', category) |
|||
if request.method == 'GET': |
|||
address = request.GET.get('address', address) |
|||
category = request.GET.get('category', category) |
|||
|
|||
if category: |
|||
context['gmap_markers'] = MapMarker.objects.get( |
|||
marker_type__category_name__iexact=category |
|||
) |
|||
else: |
|||
context['gmap_markers'] = MapMarker.objects.all() |
|||
|
|||
if address: |
|||
latlng = geolocate(address) |
|||
if latlng: |
|||
context['gmap_center_lat'] = latlng['latitude'] |
|||
context['gmap_center_lng'] = latlng['longitude'] |
|||
else: |
|||
context['error'] = "Please try another address." |
|||
|
|||
return render(request, 'maps/gmap.html', context) |
|||
|
|||
|
|||
def markers(request): |
|||
# Show all categories but Sales Centers |
|||
data = serializers.serialize("json", MapMarker.objects.all().order_by('category__position', 'city'), |
|||
use_natural_keys=True) |
|||
return HttpResponse(data, mimetype='applicaton/javascript') |
|||
|
|||
|
|||
def categories(request): |
|||
data = serializers.serialize("json", MarkerCategory.objects.all().order_by('position'), use_natural_keys=True) |
|||
return HttpResponse(data, mimetype='applicaton/javascript') |
|||
|
|||
|
|||
def director_by_boundary(request, boundary_code): |
|||
# get a director based on a boundarycode (zip/postal/country code) |
|||
data = serializers.serialize("json", SalesDirector.objects.filter(salesboundary__boundary_code=boundary_code), |
|||
use_natural_keys=True) |
|||
return HttpResponse(data, mimetype='applicaton/javascript') |
|||
|
|||
|
|||
def gmap_search(request): |
|||
context = {} |
|||
return render(request, 'maps/gmap_search.html', context) |
|||
|
|||
|
|||
def dump_csv(request): |
|||
all_markers = MapMarker.objects.all() |
|||
|
|||
print(('# markers: ', len(all_markers))) |
|||
|
|||
# all_markers should now have all the things... |
|||
response = HttpResponse(mimetype='text/csv') |
|||
response['Content-Disposition'] = 'attachment; filename=map_markers.csv' |
|||
|
|||
# writer = csv.writer(response, quoting=csv.QUOTE_MINIMAL, lineterminator='\n') |
|||
writer = gmap.utils.UnicodeWriter(response, quoting=csv.QUOTE_MINIMAL, lineterminator='\n') |
|||
|
|||
for marker in all_markers: |
|||
row = marker.csv_row() |
|||
# print 'row is: ', row |
|||
|
|||
# repr because there are non-ascii characters somewhere |
|||
writer.writerow(row) |
|||
|
|||
''' |
|||
writer.writerow(['First row', 'Foo', 'Bar', 'Baz']) |
|||
writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"]) |
|||
''' |
|||
|
|||
return response |
|||
|
|||
|
|||
def populatefields(request): |
|||
all_markers = MapMarker.objects.all() |
|||
start_time = time.time() |
|||
|
|||
# loop over all map markers and update their state and country fields |
|||
for marker in all_markers: |
|||
reverse_addy = georeverse(marker.latitude, marker.longitude) |
|||
|
|||
if reverse_addy['country']: |
|||
marker.country = reverse_addy['country'] |
|||
|
|||
if reverse_addy['state']: |
|||
marker.state = reverse_addy['state'] |
|||
|
|||
marker.save() |
|||
|
|||
end_time = time.time() |
|||
return HttpResponse(end_time - start_time) |
|||
|
|||
|
|||
def process_sales_row(row_id, row, errors): |
|||
try: |
|||
sales_director = SalesDirector.objects.get(name=row[0]) |
|||
|
|||
except SalesDirector.DoesNotExist: |
|||
sales_director = SalesDirector() |
|||
|
|||
sales_director.from_csv(row, row_id + 1, errors) |
|||
|
|||
|
|||
def process_marker_row(row_id, row, errors): |
|||
try: |
|||
marker = MapMarker.objects.get(name=row[0], zipcode=row[15]) |
|||
|
|||
except: |
|||
marker = MapMarker() |
|||
|
|||
marker.from_csv(row, row_id + 1, errors) |
|||
|
|||
|
|||
# TODO: return errors? |
|||
def process_row(row_id, row, errors): |
|||
if row[1] == '2': |
|||
|
|||
process_sales_row(row_id, row, errors) |
|||
|
|||
else: |
|||
|
|||
process_marker_row(row_id, row, errors) |
|||
|
|||
|
|||
def read_csv(request): |
|||
if request.method == 'POST' and 'datafile' in request.FILES: |
|||
|
|||
# it's conceivable the user could upload a file large enough |
|||
# it gets split into chunks - to handle this we just direct all |
|||
# the chunks to a temp file and process that |
|||
|
|||
# note that the tempfile will be deleted as soon as |
|||
# the with block is completes |
|||
num_processed = -1 |
|||
delta = 0 |
|||
errors = [] |
|||
|
|||
if request.FILES['datafile'].multiple_chunks(): |
|||
MapMarker.objects.all().delete() |
|||
|
|||
delta = time.clock() |
|||
|
|||
with tempfile.TemporaryFile() as local_file: |
|||
|
|||
for chunk in request.FILES['datafile'].chunks(): |
|||
local_file.write(chunk) |
|||
|
|||
local_file.seek(0) |
|||
|
|||
for row_id, row in enumerate(gmap.utils.UnicodeReader(local_file)): |
|||
|
|||
try: |
|||
process_row(row_id, row, errors) |
|||
|
|||
except Exception as inst: |
|||
errors.append("%s : Unable to import entry - %s" % (row_id, inst)) |
|||
|
|||
num_processed = row_id |
|||
|
|||
delta = time.clock() - delta |
|||
|
|||
else: |
|||
|
|||
delta = time.clock() |
|||
|
|||
for row_id, row in enumerate(gmap.utils.UnicodeReader(request.FILES['datafile'])): |
|||
# try: |
|||
process_row(row_id, row, errors) |
|||
|
|||
# except Exception as inst: |
|||
# errors.append("%s : Unable to import entry - %s" % (row_id, inst)) |
|||
|
|||
num_processed = row_id |
|||
|
|||
delta = time.clock() - delta |
|||
|
|||
if len(errors) > 1: |
|||
# Strip off errors result from Excel export garbage (the bottom two entries) |
|||
# |
|||
bottoms = errors[-2:] |
|||
rows = [row.split(':')[0].strip() for row in bottoms] |
|||
|
|||
if int(rows[0]) == row_id: |
|||
errors = errors[0:-2] |
|||
|
|||
if errors: |
|||
return render_to_response('maps/gmap_import_errors.html', {'errors': errors}) |
|||
|
|||
else: |
|||
return HttpResponseRedirect('/gmap/mapmarker/') |
|||
|
|||
else: |
|||
# todo - can I make django redirect to referring page? |
|||
return HttpResponseRedirect('/gmap/') |
|||
@ -1 +0,0 @@ |
|||
# Create your tests here. |
|||
@ -1,3 +0,0 @@ |
|||
from django.test import TestCase |
|||
|
|||
# Create your tests here. |
|||
@ -1,16 +0,0 @@ |
|||
""" |
|||
This file demonstrates writing tests using the unittest module. These will pass |
|||
when you run "manage.py test". |
|||
|
|||
Replace this with more appropriate tests for your application. |
|||
""" |
|||
|
|||
from django.test import TestCase |
|||
|
|||
|
|||
class SimpleTest(TestCase): |
|||
def test_basic_addition(self): |
|||
""" |
|||
Tests that 1 + 1 always equals 2. |
|||
""" |
|||
self.assertEqual(1 + 1, 2) |
|||
@ -1,22 +0,0 @@ |
|||
from django.test import TestCase |
|||
from django.contrib.auth.models import User |
|||
|
|||
from . import models |
|||
|
|||
|
|||
class PaysTest(TestCase): |
|||
def setUp(self): |
|||
self.msg = models.PrivateMessages.objects.create( |
|||
sender=User.objects.all()[0], |
|||
recepient=User.objects.all()[0], |
|||
text='test init text' |
|||
) |
|||
|
|||
def tearDown(self): |
|||
models.PrivateMessages.objects.all().delete() |
|||
|
|||
def check_ret_msgs(self): |
|||
"""check return messages""" |
|||
request = self.factory.get('/message/') |
|||
self.assertIsInstance(models.PrivateMessages.objects.get_my_messages(request), int, 'checking ret type') |
|||
self.assertGreater(models.PrivateMessages.objects.get_my_messages(request), 0, 'checking msg count') |
|||
@ -1 +0,0 @@ |
|||
# Create your tests here. |
|||
@ -1,4 +0,0 @@ |
|||
#gmap_canvas { |
|||
width: 500px; |
|||
height: 300px; |
|||
} |
|||
|
Before Width: 640 | Height: 908 | Size: 43 KiB |
|
Before Width: 100 | Height: 100 | Size: 4.4 KiB |
@ -1 +0,0 @@ |
|||
# Create your tests here. |
|||
@ -1 +0,0 @@ |
|||
# Create your tests here. |
|||
@ -1 +0,0 @@ |
|||
# Create your tests here. |
|||
@ -1,135 +0,0 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block js %} |
|||
{{ block.super }} |
|||
<script src="{{ STATIC_URL }}js/cirrus.js"></script> |
|||
<script src="https://maps-api-ssl.google.com/maps/api/js?v=3.3&sensor=false&libraries=geometry" |
|||
type="text/javascript"></script> |
|||
<script src="/static/js/jquery.lightbox-0.5.js"></script> |
|||
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js" |
|||
type="text/javascript"></script> |
|||
<script src="/static/js/gmap_script_updated.js" type="text/javascript"></script> |
|||
<link href="/static/css/gmaps_style.css" rel="stylesheet" type="text/css" media="screen"> |
|||
<link href="/static/css/jquery.lightbox-0.5.css" rel="stylesheet" type="text/css" media="screen"> |
|||
{% endblock js %} |
|||
|
|||
{% block main %} |
|||
<div class="container"> |
|||
<div class="tagline"> |
|||
<span>Cirrus Locator</span> |
|||
</div> |
|||
|
|||
<div class="section" id="themap"> |
|||
<section> |
|||
<div class="number-info"> |
|||
<div class="contact"> |
|||
</div> |
|||
<div class="contact-type"> |
|||
<span class="title">General Inquiries</span> |
|||
|
|||
<div class="number-contain"> |
|||
<div class="type">TOLL-FREE</div> |
|||
<div class="number">800.279.4322</div> |
|||
</div> |
|||
<div class="number-contain"> |
|||
<div class="type">INTERNATIONAL</div> |
|||
<div class="number">+1.218.529.7200</div> |
|||
</div> |
|||
|
|||
</div> |
|||
<div class="contact-type"> |
|||
<span class="title">Sales</span> |
|||
|
|||
<div class="number-contain"> |
|||
<div class="type">TOLL-FREE</div> |
|||
<div class="number">877.424.7787</div> |
|||
</div> |
|||
<div class="number-contain"> |
|||
<div class="type">INTERNATIONAL</div> |
|||
<div class="number">+1.218.529.7292</div> |
|||
</div> |
|||
</div> |
|||
<div class="button web-request"> |
|||
<a href="/webrequest/">WEB REQUEST</a> |
|||
</div> |
|||
<div class="button send-email"> |
|||
<a href="mailto:info@cirrusaircraft.com">SEND EMAIL</a> |
|||
</div> |
|||
</div> |
|||
<div class="form"> |
|||
|
|||
<div class="right-box"> |
|||
<div class="region_buttons"> |
|||
<a href="/static/img/region_map.png" class="bigmap usmap"> |
|||
<img src="/static/img/icons/region_map_button.png"/> |
|||
</a> |
|||
|
|||
<a href="/static/img/INTL_Sales_Team.pdf" class="internationalmap" target="_blank"> |
|||
<img src="/static/img/icons/country_map_button.png"/> |
|||
</a> |
|||
|
|||
<a href="/static/img/ChinaSalesList.pdf" class="internationalmap" target="_blank"> |
|||
<img src="/static/img/icons/china_map_button.png"/> |
|||
</a> |
|||
</div> |
|||
|
|||
<div class="locator_image"> |
|||
<img src="/static/img/locator_plane.png"/> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
<form id="gmap_search_form"> |
|||
|
|||
<p>Use the locator below to find a Regional Sales Director , |
|||
International Sales Center, Cirrus Sales Center, Authorized |
|||
Service Center (ASC), Cirrus Training Center (CTC), or |
|||
Cirrus Standardized Instructor Pilot (CSIP). |
|||
</p> |
|||
|
|||
<br/> |
|||
|
|||
<hr/> |
|||
|
|||
<span><input type="radio" name="locator" value="zip" checked/>ZIP Code</span> |
|||
<input id="zipcode" type="text" name="zipcode"/> |
|||
<select id="radius"> |
|||
<option value="100">100 miles</option> |
|||
<option value="200">200 miles</option> |
|||
<option value="300">300 miles</option> |
|||
<option selected="selected" value="500">500 miles</option> |
|||
</select><br/> |
|||
<span><input type="radio" name="locator" value="state"/>State</span> |
|||
{{ form.state }} |
|||
<br/> |
|||
<span><input type="radio" name="locator" value="country"/>Country</span> |
|||
{{ form.country }} |
|||
<br/> |
|||
<hr/> |
|||
<input id="gmap_search_submit" type="submit" value="SUBMIT"/> |
|||
</form> |
|||
</div> |
|||
</section> |
|||
</div> |
|||
|
|||
|
|||
<div class="section" id="theshops"> |
|||
<section> |
|||
<p class="results"></p> |
|||
|
|||
<p class="results_amount"></p> |
|||
|
|||
<p class="multiplesales"></p> |
|||
|
|||
<div id="gmap_categories"> |
|||
<ul></ul> |
|||
</div> |
|||
<ul class="locations"> |
|||
<!-- Use js/jquery to add locations here $('ul.locations').append(stuff); --> |
|||
</ul> |
|||
</section> |
|||
</div> |
|||
|
|||
|
|||
</div> |
|||
{% endblock main %} |
|||
@ -1,15 +0,0 @@ |
|||
{% extends "admin/base_site.html" %} |
|||
|
|||
{% block title %}CSV Import Summary{% endblock %} |
|||
|
|||
{% block content %} |
|||
<div id="content-main"> |
|||
<p>The following entries could not be imported:</p> |
|||
<ul> |
|||
{% for error in errors %} |
|||
<li>{% autoescape off %} {{ error }} {% endautoescape %}</p></li> |
|||
{% endfor %} |
|||
</ul> |
|||
<p>Return to the <a href="{% url admin:index %}">Administration Page</a>.</p> |
|||
</div> |
|||
{% endblock %} |
|||
@ -1,6 +0,0 @@ |
|||
<div id="gmap_search"> |
|||
<form id="gmap_search_form" method="get" action="{% url gmap.views.showmap address='' %}"> |
|||
<input type="search" id="gmap_search" placeholder="55811" name="address"> |
|||
<input type="submit" value="Search" id="gmap_search_submit"> |
|||
</form> |
|||
</div> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue