diff --git a/README.md b/README.md index 6741545..1913205 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,15 @@ INSTALLED_APPS = [ ] ``` +Then, add the url in your urls.py + +``` +urlpatterns = [ + # other urls... + path('address/', include('address.urls')), +] +``` + You can either store your Google API key in an environment variable as `GOOGLE_API_KEY` or you can specify the key in `settings.py`. If you have an environment variable set it will override what you put in settings.py. For more information, including enabling the Google Places API, refer to [the example site](https://github.com/furious-luke/django-address/blob/master/example_site/README.md). @@ -38,6 +47,16 @@ You can either store your Google API key in an environment variable as `GOOGLE_A GOOGLE_API_KEY = 'AIzaSyD--your-google-maps-key-SjQBE' ``` +## Settings +Is possible to specify custom settings in your settings module. +For example, to get address only for the Australia add these to your settings + +```python +ADDRESS_SETTINGS = { + "country": ["AU"] +} +``` + # The Model The rationale behind the model structure is centered on trying to make diff --git a/address/fields.py b/address/fields.py new file mode 100644 index 0000000..69a544c --- /dev/null +++ b/address/fields.py @@ -0,0 +1,29 @@ +## +# A field for addresses in other models. +## +from django.db import models +from . import models as address_models +from . import forms as address_forms + + +class AddressField(models.ForeignKey): + description = 'An address' + + def __init__(self, *args, **kwargs): + kwargs['to'] = 'address.Address' + # The address should be set to null when deleted if the relationship could be null + default_on_delete = models.SET_NULL if kwargs.get('null', False) else models.CASCADE + kwargs['on_delete'] = kwargs.get('on_delete', default_on_delete) + super(AddressField, self).__init__(*args, **kwargs) + + def contribute_to_class(self, cls, name, virtual_only=False): + from address.compat import compat_contribute_to_class + + compat_contribute_to_class(self, cls, name, virtual_only) + + setattr(cls, self.name, address_models.AddressDescriptor(self)) + + def formfield(self, **kwargs): + defaults = dict(form_class=address_forms.AddressField) + defaults.update(kwargs) + return super(AddressField, self).formfield(**defaults) \ No newline at end of file diff --git a/address/models.py b/address/models.py index 9978c7b..d2f8540 100644 --- a/address/models.py +++ b/address/models.py @@ -16,7 +16,7 @@ basestring = (str, bytes) unicode = str -__all__ = ['Country', 'State', 'Locality', 'Address', 'AddressField'] +__all__ = ['Country', 'State', 'Locality', 'Address',] class InconsistentDictError(Exception): @@ -295,30 +295,4 @@ class AddressDescriptor(ForwardManyToOneDescriptor): def __set__(self, inst, value): super(AddressDescriptor, self).__set__(inst, to_python(value)) -## -# A field for addresses in other models. -## - - -class AddressField(models.ForeignKey): - description = 'An address' - - def __init__(self, *args, **kwargs): - kwargs['to'] = 'address.Address' - # The address should be set to null when deleted if the relationship could be null - default_on_delete = models.SET_NULL if kwargs.get('null', False) else models.CASCADE - kwargs['on_delete'] = kwargs.get('on_delete', default_on_delete) - super(AddressField, self).__init__(*args, **kwargs) - - def contribute_to_class(self, cls, name, virtual_only=False): - from address.compat import compat_contribute_to_class - - compat_contribute_to_class(self, cls, name, virtual_only) - - setattr(cls, self.name, AddressDescriptor(self)) - def formfield(self, **kwargs): - from .forms import AddressField as AddressFormField - defaults = dict(form_class=AddressFormField) - defaults.update(kwargs) - return super(AddressField, self).formfield(**defaults) diff --git a/address/templates/__init__.py b/address/templates/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/address/templates/address/__init__.py b/address/templates/address/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/address/static/address/js/address.js b/address/templates/address/address.js similarity index 82% rename from address/static/address/js/address.js rename to address/templates/address/address.js index 3aa84bf..36ed5f3 100644 --- a/address/static/address/js/address.js +++ b/address/templates/address/address.js @@ -1,12 +1,15 @@ $(function () { $('input.address').each(function () { + let address_settings = {{ address_settings|safe }}; var self = $(this); var cmps = $('#' + self.attr('name') + '_components'); var fmtd = $('input[name="' + self.attr('name') + '_formatted"]'); self.geocomplete({ details: cmps, - detailsAttribute: 'data-geo' - }).change(function () { + detailsAttribute: 'data-geo', + ...address_settings, + } + ).change(function () { if (self.val() != fmtd.val()) { var cmp_names = [ 'country', diff --git a/address/tests/test_models.py b/address/tests/test_models.py index 3d2488b..e4719ca 100644 --- a/address/tests/test_models.py +++ b/address/tests/test_models.py @@ -2,7 +2,8 @@ from django.db import IntegrityError from django.core.exceptions import ValidationError -from address.models import Country, State, Locality, Address, AddressField +from address.models import Country, State, Locality, Address +from address.fields import AddressField from address.models import to_python # Python 3 fixes. diff --git a/address/urls.py b/address/urls.py new file mode 100644 index 0000000..b0c74dc --- /dev/null +++ b/address/urls.py @@ -0,0 +1,7 @@ +from django.urls import path + +from .views import AddressJS + +urlpatterns = [ + path('address.js', AddressJS.as_view(), name="address.js"), +] diff --git a/address/views.py b/address/views.py new file mode 100644 index 0000000..a7a9772 --- /dev/null +++ b/address/views.py @@ -0,0 +1,14 @@ +import json +from django.views.generic import TemplateView +from django.conf import settings + + +class AddressJS(TemplateView): + content_type = "text/javascript" + template_name = "address/address.js" + + def get_context_data(self, **kwargs): + context = super().get_context_data() + address_settings = getattr(settings, "ADDRESS_SETTINGS", {}) + context["address_settings"] = json.dumps(address_settings) + return context diff --git a/address/widgets.py b/address/widgets.py index f4fc914..c7de8a3 100644 --- a/address/widgets.py +++ b/address/widgets.py @@ -5,6 +5,7 @@ from django.conf import settings from django.utils.html import escape from django.utils.safestring import mark_safe +from django.urls import reverse from .models import Address @@ -32,7 +33,7 @@ class Media: js = [ 'https://maps.googleapis.com/maps/api/js?libraries=places&key=%s' % settings.GOOGLE_API_KEY, 'js/jquery.geocomplete.min.js', - 'address/js/address.js', + reverse('address.js'), ] if JQUERY_URL: diff --git a/example_site/example_site/urls.py b/example_site/example_site/urls.py index bc29c99..22c807f 100644 --- a/example_site/example_site/urls.py +++ b/example_site/example_site/urls.py @@ -1,9 +1,12 @@ from django.contrib import admin -from django.urls import path +from django.urls import path, include -from person import views as person +from person import views as person_views +from address import views as address_views +from address import urls as address_urls urlpatterns = [ - path('', person.home, name='home'), + path('', person_views.home, name='home'), path('admin/', admin.site.urls), + path('address/', include('address.urls')), ] diff --git a/example_site/person/admin.py b/example_site/person/admin.py index a1b02dd..9c2a9ef 100644 --- a/example_site/person/admin.py +++ b/example_site/person/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from address.models import AddressField +from address.fields import AddressField from address.forms import AddressWidget from .models import Person diff --git a/example_site/person/migrations/0001_initial.py b/example_site/person/migrations/0001_initial.py index cc134b8..182ac4c 100644 --- a/example_site/person/migrations/0001_initial.py +++ b/example_site/person/migrations/0001_initial.py @@ -1,6 +1,7 @@ # Generated by Django 2.0.3 on 2018-03-29 22:34 import address.models +import address.fields from django.db import migrations, models import django.db.models.deletion @@ -18,7 +19,7 @@ class Migration(migrations.Migration): name='Person', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('address', address.models.AddressField(on_delete=django.db.models.deletion.CASCADE, to='address.Address')), + ('address', address.fields.AddressField(on_delete=django.db.models.deletion.CASCADE, to='address.Address')), ], ), ] diff --git a/example_site/person/migrations/0003_auto_20200628_1920.py b/example_site/person/migrations/0003_auto_20200628_1920.py index 601c914..d9ab9b5 100644 --- a/example_site/person/migrations/0003_auto_20200628_1920.py +++ b/example_site/person/migrations/0003_auto_20200628_1920.py @@ -1,6 +1,7 @@ # Generated by Django 3.0.6 on 2020-06-28 19:20 import address.models +import address.fields from django.db import migrations, models import django.db.models.deletion @@ -21,6 +22,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='person', name='address', - field=address.models.AddressField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='address.Address'), + field=address.fields.AddressField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='address.Address'), ), ] diff --git a/example_site/person/models.py b/example_site/person/models.py index 575a7b5..b508169 100644 --- a/example_site/person/models.py +++ b/example_site/person/models.py @@ -1,5 +1,5 @@ from django.db import models -from address.models import AddressField +from address.fields import AddressField class Person(models.Model): diff --git a/example_site/person/views.py b/example_site/person/views.py index 18e637b..22a0466 100644 --- a/example_site/person/views.py +++ b/example_site/person/views.py @@ -2,10 +2,9 @@ from django.shortcuts import render from address.models import Address -from .forms import PersonForm - def home(request): + from .forms import PersonForm success = False addresses = Address.objects.all() if settings.GOOGLE_API_KEY: diff --git a/setup.py b/setup.py index 4dd779e..ab9d61d 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import find_packages, setup -version = '0.2.5' +version = '0.2.6' if sys.argv[-1] == 'tag': print("Tagging the version on github:")