Skip to content

Commit 9855da6

Browse files
authored
Add django point field for factories (#19)
* add django point field for factories * fix flake8 * install gdal in github workflow * install spatialite github workflow * dont specify spatialite path, so github workflow hopefully works ... * inherit from proper test case ... * rename test case * mark explicitly for db, even though other test cases dont need it .. * threw in the towel trying to get osx to work, added simple dockerfile setup .. * run against many versions * try to also replace DRF in github workflow * terminate regex replace * fix replacing DRF version * debug prints * fix sed replace * fix drf ver ... * drop support for django < 2? * bump version -> 0.0.4
1 parent 553e879 commit 9855da6

File tree

11 files changed

+125
-8
lines changed

11 files changed

+125
-8
lines changed

.github/workflows/pythonpackage.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@ jobs:
1111
strategy:
1212
matrix:
1313
python-version: [3.6, 3.7, 3.8]
14-
django-version: ['<2', '<3', '>=3']
14+
django-version: ['<3', '>=3']
1515

1616
steps:
1717
- uses: actions/checkout@v2
18+
- name: Install GDAL & spatialite
19+
run: |
20+
sudo add-apt-repository ppa:ubuntugis/ppa && sudo apt-get update
21+
sudo apt-get install libgdal-dev libsqlite3-mod-spatialite
1822
- name: Set up Python ${{ matrix.python-version }}
1923
uses: actions/setup-python@v1
2024
with:
@@ -30,8 +34,15 @@ jobs:
3034
${{ runner.os }}-
3135
- name: Install dependencies
3236
run: |
33-
echo "Django version set to '${{ matrix.django-version }}' in requirements.txt"
37+
export DRF_VERSION=3.12.4
38+
39+
if [ '${{ matrix.django-version }}' == '<2' ]; then
40+
DRF_VERSION=3.11.2
41+
fi
42+
43+
echo "Setting versions Django -> ${{ matrix.django-version }} DRF -> $DRF_VERSION in requirements.txt"
3444
sed -i 's/Django==.*/Django${{ matrix.django-version }}/' requirements.txt
45+
sed -i "s/djangorestframework==.*/djangorestframework==$DRF_VERSION/" requirements.txt
3546
pip install -r requirements.txt
3647
- name: Lint with flake8
3748
run: |

Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM python:3.9.2
2+
3+
# Spatial packages and such
4+
RUN apt-get update && apt-get install -y libgdal-dev libsqlite3-mod-spatialite
5+
6+
# Python reqs
7+
ADD requirements.txt .
8+
RUN pip install -r requirements.txt
9+
10+
# add all of our source + config
11+
ADD ckc/ /src/ckc/
12+
ADD testproject/ /src/testproject
13+
ADD tests/ /src/tests
14+
ADD setup.cfg /src
15+
WORKDIR /src

README.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ $ twine upload dist/*
3333
## tests
3434

3535
```bash
36-
# get into a virtual env of some kind
37-
$ pip install -r requirements.txt
38-
$ pytest
36+
$ docker build -t django-ckc . && docker run django-ckc pytest
3937
```
4038

4139
## what's in this
@@ -60,6 +58,29 @@ class MySerializer(DefaultUserCreateMixin, ModelSerializer):
6058
model = YourModel
6159
```
6260

61+
#### `DjangoGeoPointProvider`
62+
63+
Helps generate geo points in Factory Boy factories.
64+
65+
```py
66+
# factories.py
67+
class SomeLocationFactory(DjangoModelFactory):
68+
location = factory.Faker('geo_point', country_code='US')
69+
70+
class Meta:
71+
model = SomeLocation
72+
73+
# test_whatever.py
74+
from django.contrib.gis.geos import Point
75+
76+
77+
class WhateverTest(TestCase):
78+
def test_something(self):
79+
SomeLocationFactory() # random location
80+
SomeLocationFactory(location=Point(x=60, y=60)) # specified location
81+
```
82+
83+
6384
#### `./manage.py` commands
6485

6586
| command | description|

ckc/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# We import here to run the faker factory add_provider stuff...
2+
from . import providers # noqa: F401

ckc/providers.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Doing a try/except here so we don't force end users of the
2+
# django-ckc module to install factory boy.
3+
try:
4+
import factory
5+
from django.contrib.gis.geos import Point
6+
from faker.providers import BaseProvider
7+
8+
class DjangoGeoPointProvider(BaseProvider):
9+
"""Custom helper class giving us the 'geo_point' provider, example:
10+
11+
location = factory.Faker('geo_point', country_code='US')
12+
13+
(note, you must call factory.Faker.add_provider(DjangoGeoPointProvider) to add
14+
this provider!)
15+
"""
16+
17+
def geo_point(self, **kwargs):
18+
kwargs['coords_only'] = True
19+
faker = factory.faker.faker.Faker()
20+
21+
# local_latlng returns something like:
22+
# ('40.72371', '-73.95097', 'Greenpoint', 'US', 'America/New_York')
23+
coords = faker.local_latlng(**kwargs)
24+
return Point(x=float(coords[1]), y=float(coords[0]), srid=4326)
25+
26+
factory.Faker.add_provider(DjangoGeoPointProvider)
27+
except ImportError:
28+
pass

requirements.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
# These requirements are for local development and testing of the module
2+
13
# python packaging
24
twine==3.1.1
35

46
# django stuff
57
Django==3.1.8
6-
djangorestframework==3.11.2
8+
djangorestframework==3.12.4
9+
10+
# factories
11+
factory-boy==3.2.0
712

813
# tests
914
pytest==5.4.1

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ name = django-ckc
3939
author = Eric Carmichael
4040
author_email = [email protected]
4141
description = tools, utilities, etc. we use across projects @ ckc
42-
version = 0.0.3
42+
version = 0.0.4
4343
url = https://github.com/ckcollab/django-ckc
4444
keywords =
4545
django

testproject/settings.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66
BASE_DIR = os.path.dirname(__file__)
77

8+
# NOTE: We're using Geospatial sqlite jazz
89
DATABASES = {
910
"default": {
10-
"ENGINE": "django.db.backends.sqlite3",
11+
"ENGINE": "django.contrib.gis.db.backends.spatialite",
1112
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
1213
}
1314
}
@@ -32,6 +33,7 @@
3233
"django.contrib.contenttypes",
3334
"django.contrib.sessions",
3435
"django.contrib.staticfiles",
36+
"django.contrib.gis",
3537

3638
"ckc",
3739

testproject/testapp/factories.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import factory
2+
3+
from factory.django import DjangoModelFactory
4+
5+
from testapp.models import Location
6+
7+
8+
class LocationFactory(DjangoModelFactory):
9+
geo_point = factory.Faker('geo_point', country_code='US')
10+
11+
class Meta:
12+
model = Location

testproject/testapp/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from django.contrib.auth import get_user_model
2+
from django.contrib.gis.db.models import PointField
23
from django.db import models
34

45
from ckc.models import SoftDeletableModel
@@ -17,3 +18,7 @@ class ModelWithACreator(models.Model):
1718

1819
class ModelWithADifferentNamedCreator(models.Model):
1920
owner = models.ForeignKey(User, on_delete=models.CASCADE)
21+
22+
23+
class Location(models.Model):
24+
geo_point = PointField()

0 commit comments

Comments
 (0)