Skip to content

Commit 422e92d

Browse files
mehdipourfarblag
authored andcommitted
support django 2
1 parent 64ec56d commit 422e92d

File tree

7 files changed

+178
-35
lines changed

7 files changed

+178
-35
lines changed

.travis.yml

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ env:
2222
- DJANGO_VERSION='Django>=1.9,<1.10'
2323
- DJANGO_VERSION='Django>=1.10,<1.11'
2424
- DJANGO_VERSION='Django>=1.11,<2.0'
25+
- DJANGO_VERSION='Django>=2.0,<2.1'
2526
- DJANGO_VERSION='https://github.com/django/django/archive/master.tar.gz'
2627

2728
matrix:
@@ -36,6 +37,10 @@ matrix:
3637
env: DJANGO_VERSION='Django>=1.10,<1.11'
3738
- python: "3.3"
3839
env: DJANGO_VERSION='Django>=1.11,<2.0'
40+
- python: "2.7"
41+
env: DJANGO_VERSION='Django>=2.0,<2.1'
42+
- python: "3.3"
43+
env: DJANGO_VERSION='Django>=2.0,<2.1'
3944
- python: "2.7"
4045
env: DJANGO_VERSION='https://github.com/django/django/archive/master.tar.gz'
4146
- python: "3.3"

cities/conf.py

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from importlib import import_module
44
from collections import defaultdict
5+
6+
import django
57
from django.conf import settings as django_settings
68
from django.core.exceptions import ImproperlyConfigured
79
from django.utils.translation import ugettext_lazy as _
@@ -363,3 +365,4 @@ def create_plugins():
363365
# Users who want better postal codes can flip this on (developers of
364366
# django-cities itself probably will), but most probably won't want to
365367
VALIDATE_POSTAL_CODES = getattr(django_settings, 'CITIES_VALIDATE_POSTAL_CODES', False)
368+
DJANGO_VERSION = float('.'.join(map(str, django.VERSION[:2])))

cities/migrations/0001_initial.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import swapper
88

9+
from cities.models import SET_NULL_OR_CASCADE
10+
911

1012
class Migration(migrations.Migration):
1113

@@ -81,7 +83,7 @@ class Migration(migrations.Migration):
8183
('location', django.contrib.gis.db.models.fields.PointField(srid=4326)),
8284
('population', models.IntegerField()),
8385
('alt_names', models.ManyToManyField(to='cities.AlternativeName')),
84-
('city', models.ForeignKey(to=swapper.get_model_name('cities', 'City'))),
86+
('city', models.ForeignKey(to=swapper.get_model_name('cities', 'City'), on_delete=SET_NULL_OR_CASCADE)),
8587
],
8688
options={
8789
'abstract': False,
@@ -99,7 +101,7 @@ class Migration(migrations.Migration):
99101
('subregion_name', models.CharField(max_length=100, db_index=True)),
100102
('district_name', models.CharField(max_length=100, db_index=True)),
101103
('alt_names', models.ManyToManyField(to='cities.AlternativeName')),
102-
('country', models.ForeignKey(related_name='postal_codes', to=swapper.get_model_name('cities', 'Country'))),
104+
('country', models.ForeignKey(related_name='postal_codes', to=swapper.get_model_name('cities', 'Country'), on_delete=SET_NULL_OR_CASCADE)),
103105
],
104106
options={
105107
'abstract': False,
@@ -114,7 +116,7 @@ class Migration(migrations.Migration):
114116
('name_std', models.CharField(max_length=200, verbose_name='standard name', db_index=True)),
115117
('code', models.CharField(max_length=200, db_index=True)),
116118
('alt_names', models.ManyToManyField(to='cities.AlternativeName')),
117-
('country', models.ForeignKey(to=swapper.get_model_name('cities', 'Country'))),
119+
('country', models.ForeignKey(to=swapper.get_model_name('cities', 'Country'), on_delete=SET_NULL_OR_CASCADE)),
118120
],
119121
options={
120122
'abstract': False,
@@ -129,7 +131,7 @@ class Migration(migrations.Migration):
129131
('name_std', models.CharField(max_length=200, verbose_name='standard name', db_index=True)),
130132
('code', models.CharField(max_length=200, db_index=True)),
131133
('alt_names', models.ManyToManyField(to='cities.AlternativeName')),
132-
('region', models.ForeignKey(to='cities.Region')),
134+
('region', models.ForeignKey(to='cities.Region', on_delete=SET_NULL_OR_CASCADE)),
133135
],
134136
options={
135137
'abstract': False,
@@ -138,16 +140,16 @@ class Migration(migrations.Migration):
138140
migrations.AddField(
139141
model_name='city',
140142
name='country',
141-
field=models.ForeignKey(to=swapper.get_model_name('cities', 'Country')),
143+
field=models.ForeignKey(to=swapper.get_model_name('cities', 'Country'), on_delete=SET_NULL_OR_CASCADE),
142144
),
143145
migrations.AddField(
144146
model_name='city',
145147
name='region',
146-
field=models.ForeignKey(blank=True, to='cities.Region', null=True),
148+
field=models.ForeignKey(blank=True, to='cities.Region', null=True, on_delete=SET_NULL_OR_CASCADE),
147149
),
148150
migrations.AddField(
149151
model_name='city',
150152
name='subregion',
151-
field=models.ForeignKey(blank=True, to='cities.Subregion', null=True),
153+
field=models.ForeignKey(blank=True, to='cities.Subregion', null=True, on_delete=SET_NULL_OR_CASCADE),
152154
),
153155
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Generated by Django 2.0 on 2018-01-08 07:06
2+
3+
import cities.models
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('cities', '0010_adjust_unique_attributes'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='city',
17+
name='country',
18+
field=models.ForeignKey(on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='cities', to=settings.CITIES_COUNTRY_MODEL),
19+
),
20+
migrations.AlterField(
21+
model_name='city',
22+
name='region',
23+
field=models.ForeignKey(blank=True, null=True, on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='cities', to='cities.Region'),
24+
),
25+
migrations.AlterField(
26+
model_name='city',
27+
name='subregion',
28+
field=models.ForeignKey(blank=True, null=True, on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='cities', to='cities.Subregion'),
29+
),
30+
migrations.AlterField(
31+
model_name='country',
32+
name='continent',
33+
field=models.ForeignKey(null=True, on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='countries', to=settings.CITIES_CONTINENT_MODEL),
34+
),
35+
migrations.AlterField(
36+
model_name='district',
37+
name='city',
38+
field=models.ForeignKey(on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='districts', to=settings.CITIES_CITY_MODEL),
39+
),
40+
migrations.AlterField(
41+
model_name='postalcode',
42+
name='city',
43+
field=models.ForeignKey(blank=True, null=True, on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='postal_codes', to=settings.CITIES_CITY_MODEL),
44+
),
45+
migrations.AlterField(
46+
model_name='postalcode',
47+
name='district',
48+
field=models.ForeignKey(blank=True, null=True, on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='postal_codes', to='cities.District'),
49+
),
50+
migrations.AlterField(
51+
model_name='postalcode',
52+
name='region',
53+
field=models.ForeignKey(blank=True, null=True, on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='postal_codes', to='cities.Region'),
54+
),
55+
migrations.AlterField(
56+
model_name='postalcode',
57+
name='subregion',
58+
field=models.ForeignKey(blank=True, null=True, on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='postal_codes', to='cities.Subregion'),
59+
),
60+
migrations.AlterField(
61+
model_name='region',
62+
name='country',
63+
field=models.ForeignKey(on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='regions', to=settings.CITIES_COUNTRY_MODEL),
64+
),
65+
migrations.AlterField(
66+
model_name='subregion',
67+
name='region',
68+
field=models.ForeignKey(on_delete=cities.models.SET_NULL_OR_CASCADE, related_name='subregions', to='cities.Region'),
69+
),
70+
]

cities/models.py

+65-20
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88

99
from django.db import transaction
1010
from django.utils.encoding import python_2_unicode_compatible
11-
from django.contrib.gis.db import models
11+
from django.contrib.gis.db.models import PointField
12+
from django.db import models
1213
from django.contrib.gis.geos import Point
1314

1415
from model_utils import Choices
1516
import swapper
1617

17-
from .conf import (ALTERNATIVE_NAME_TYPES, SLUGIFY_FUNCTION)
18+
from .conf import (ALTERNATIVE_NAME_TYPES, SLUGIFY_FUNCTION, DJANGO_VERSION)
1819
from .managers import AlternativeNameManager
1920
from .util import unicode_func
2021

@@ -24,9 +25,21 @@
2425
]
2526

2627

28+
if DJANGO_VERSION < 2:
29+
from django.contrib.gis.db.models import GeoManager
30+
else:
31+
from django.db.models import Manager as GeoManager
32+
2733
slugify_func = SLUGIFY_FUNCTION
2834

2935

36+
def SET_NULL_OR_CASCADE(collector, field, sub_objs, using):
37+
if field.null is True:
38+
models.SET_NULL(collector, field, sub_objs, using)
39+
else:
40+
models.CASCADE(collector, field, sub_objs, using)
41+
42+
3043
class SlugModel(models.Model):
3144
slug = models.CharField(blank=True, max_length=255, null=True)
3245

@@ -64,7 +77,7 @@ class Place(models.Model):
6477
name = models.CharField(max_length=200, db_index=True, verbose_name="ascii name")
6578
alt_names = models.ManyToManyField('AlternativeName')
6679

67-
objects = models.GeoManager()
80+
objects = GeoManager()
6881

6982
class Meta:
7083
abstract = True
@@ -117,7 +130,9 @@ class BaseCountry(Place, SlugModel):
117130
language_codes = models.CharField(max_length=250, null=True)
118131
phone = models.CharField(max_length=20)
119132
continent = models.ForeignKey(swapper.get_model_name('cities', 'Continent'),
120-
null=True, related_name='countries')
133+
null=True,
134+
related_name='countries',
135+
on_delete=SET_NULL_OR_CASCADE)
121136
tld = models.CharField(max_length=5, verbose_name='TLD')
122137
postal_code_format = models.CharField(max_length=127)
123138
postal_code_regex = models.CharField(max_length=255)
@@ -152,7 +167,8 @@ class Region(Place, SlugModel):
152167
name_std = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
153168
code = models.CharField(max_length=200, db_index=True)
154169
country = models.ForeignKey(swapper.get_model_name('cities', 'Country'),
155-
related_name='regions')
170+
related_name='regions',
171+
on_delete=SET_NULL_OR_CASCADE)
156172

157173
class Meta:
158174
unique_together = (('country', 'name'),)
@@ -175,7 +191,9 @@ class Subregion(Place, SlugModel):
175191

176192
name_std = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
177193
code = models.CharField(max_length=200, db_index=True)
178-
region = models.ForeignKey(Region, related_name='subregions')
194+
region = models.ForeignKey(Region,
195+
related_name='subregions',
196+
on_delete=SET_NULL_OR_CASCADE)
179197

180198
class Meta:
181199
unique_together = (('region', 'id', 'name'),)
@@ -198,10 +216,19 @@ class BaseCity(Place, SlugModel):
198216

199217
name_std = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
200218
country = models.ForeignKey(swapper.get_model_name('cities', 'Country'),
201-
related_name='cities')
202-
region = models.ForeignKey(Region, null=True, blank=True, related_name='cities')
203-
subregion = models.ForeignKey(Subregion, null=True, blank=True, related_name='cities')
204-
location = models.PointField()
219+
related_name='cities',
220+
on_delete=SET_NULL_OR_CASCADE)
221+
region = models.ForeignKey(Region,
222+
null=True,
223+
blank=True,
224+
related_name='cities',
225+
on_delete=SET_NULL_OR_CASCADE)
226+
subregion = models.ForeignKey(Subregion,
227+
null=True,
228+
blank=True,
229+
related_name='cities',
230+
on_delete=SET_NULL_OR_CASCADE)
231+
location = PointField()
205232
population = models.IntegerField()
206233
elevation = models.IntegerField(null=True)
207234
kind = models.CharField(max_length=10) # http://www.geonames.org/export/codes.html
@@ -232,9 +259,11 @@ class District(Place, SlugModel):
232259

233260
name_std = models.CharField(max_length=200, db_index=True, verbose_name="standard name")
234261
code = models.CharField(blank=True, db_index=True, max_length=200, null=True)
235-
location = models.PointField()
262+
location = PointField()
236263
population = models.IntegerField()
237-
city = models.ForeignKey(swapper.get_model_name('cities', 'City'), related_name='districts')
264+
city = models.ForeignKey(swapper.get_model_name('cities', 'City'),
265+
related_name='districts',
266+
on_delete=SET_NULL_OR_CASCADE)
238267

239268
class Meta:
240269
unique_together = (('city', 'name'),)
@@ -279,23 +308,39 @@ class PostalCode(Place, SlugModel):
279308
slug_contains_id = True
280309

281310
code = models.CharField(max_length=20)
282-
location = models.PointField()
311+
location = PointField()
283312

284313
country = models.ForeignKey(swapper.get_model_name('cities', 'Country'),
285-
related_name='postal_codes')
314+
related_name='postal_codes',
315+
on_delete=SET_NULL_OR_CASCADE)
286316

287317
# Region names for each admin level, region may not exist in DB
288318
region_name = models.CharField(max_length=100, db_index=True)
289319
subregion_name = models.CharField(max_length=100, db_index=True)
290320
district_name = models.CharField(max_length=100, db_index=True)
291321

292-
region = models.ForeignKey(Region, blank=True, null=True, related_name='postal_codes')
293-
subregion = models.ForeignKey(Subregion, blank=True, null=True, related_name='postal_codes')
322+
region = models.ForeignKey(Region,
323+
blank=True,
324+
null=True,
325+
related_name='postal_codes',
326+
on_delete=SET_NULL_OR_CASCADE)
327+
subregion = models.ForeignKey(Subregion,
328+
blank=True,
329+
null=True,
330+
related_name='postal_codes',
331+
on_delete=SET_NULL_OR_CASCADE)
294332
city = models.ForeignKey(swapper.get_model_name('cities', 'City'),
295-
blank=True, null=True, related_name='postal_codes')
296-
district = models.ForeignKey(District, blank=True, null=True, related_name='postal_codes')
297-
298-
objects = models.GeoManager()
333+
blank=True,
334+
null=True,
335+
related_name='postal_codes',
336+
on_delete=SET_NULL_OR_CASCADE)
337+
district = models.ForeignKey(District,
338+
blank=True,
339+
null=True,
340+
related_name='postal_codes',
341+
on_delete=SET_NULL_OR_CASCADE)
342+
343+
objects = GeoManager()
299344

300345
class Meta:
301346
unique_together = (

test_project/test_app/urls.py

+24-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
1-
from django.conf.urls import include, url
1+
from django.conf.urls import url
22
from django.contrib import admin
3+
from django.core.exceptions import ImproperlyConfigured
34

45
from cities.util import patterns
56

67

7-
urlpatterns = patterns(
8-
'',
9-
# Examples:
10-
# url(r'^$', 'test_project.views.home', name='home'),
11-
# url(r'^blog/', include('blog.urls')),
8+
app_name = "test_app"
129

13-
url(r'^admin/', include(admin.site.urls)),
14-
)
10+
try:
11+
from django.conf.urls import include
12+
# Django < 2.0
13+
urlpatterns = patterns(
14+
'',
15+
# Examples:
16+
# url(r'^$', 'test_project.views.home', name='home'),
17+
# url(r'^blog/', include('blog.urls')),
18+
19+
url(r'^admin/', include(admin.site.urls)),
20+
)
21+
except ImproperlyConfigured:
22+
# Django >= 2.0
23+
urlpatterns = patterns(
24+
'',
25+
# Examples:
26+
# url(r'^$', 'test_project.views.home', name='home'),
27+
# url(r'^blog/', include('blog.urls')),
28+
29+
url(r'^admin/', admin.site.urls),
30+
)

tox.ini

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
envlist =
33
py33-dj1.8,
44
py{27,34,35,36}-dj1.{8,9,10,11}
5+
py{34,35,36}-dj2.0
56

67
[testenv]
78
commands=python {toxinidir}/test_project/manage.py test {posargs:test_app} --noinput
@@ -13,5 +14,6 @@ deps =
1314
dj1.9: Django ~=1.9.0
1415
dj1.10: Django ~=1.10.0
1516
dj1.11: Django ~=1.11.0
17+
dj2.0: Django ~=2.0.0
1618

1719
psycopg2

0 commit comments

Comments
 (0)