Skip to content

Commit

Permalink
Merge branch 'master' into upgrade_django
Browse files Browse the repository at this point in the history
  • Loading branch information
nemesifier authored Jul 23, 2024
2 parents 7d51bad + 110abaa commit dd48b10
Show file tree
Hide file tree
Showing 15 changed files with 193 additions and 21 deletions.
30 changes: 30 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
name: Bug report
about: Open a bug report
title: "[bug] "
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of the bug or unexpected behavior.

**Steps To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**System Informatioon:**
- OS: [e.g. Ubuntu 24.04 LTS]
- Python Version: [e.g. Python 3.11.2]
- Django Version: [e.g. Django 4.2.5]
- Browser and Browser Version (if applicable): [e.g. Chromium v126.0.6478.126]
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[feature] "
labels: enhancement
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
10 changes: 10 additions & 0 deletions .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: Question
about: Please use the Discussion Forum to ask questions
title: "[question] "
labels: question
assignees: ''

---

Please use the [Discussion Forum](https://github.com/openwisp/django-rest-framework-gis/discussions) to ask questions.
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "pip" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "monthly"
commit-message:
prefix: "[deps] "
20 changes: 20 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Checklist

- [ ] I have read the [OpenWISP Contributing Guidelines](http://openwisp.io/docs/developer/contributing.html).
- [ ] I have manually tested the changes proposed in this pull request.
- [ ] I have written new test cases for new code and/or updated existing tests for changes to existing code.
- [ ] I have updated the documentation.

## Reference to Existing Issue

Closes #<issue-number>.

Please [open a new issue](https://github.com/openwisp/django-rest-framework-gis/issues/new/choose) if there isn't an existing issue yet.

## Description of Changes

Please describe these changes.

## Screenshot

Please include any relevant screenshots.
7 changes: 5 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ to be serialized as the "geometry". For example:
# as with a ModelSerializer.
fields = ('id', 'address', 'city', 'state')
If your model is geometry-less, you can set ``geo_field`` to ``None``
and a null geometry will be produced.

Using GeometrySerializerMethodField as "geo_field"
##################################################

Expand Down Expand Up @@ -755,8 +758,8 @@ Contributing
8. Document your changes
9. Send pull request

.. |Build Status| image:: https://github.com/openwisp/django-rest-framework-gis/workflows/Django%20Rest%20Framework%20Gis%20CI%20Build/badge.svg?branch=master
:target: https://github.com/openwisp/django-rest-framework-gis/actions?query=workflow%3A%22Django+Rest+Framework+Gis+CI+Build%22
.. |Build Status| image:: https://github.com/openwisp/django-rest-framework-gis/actions/workflows/ci.yml/badge.svg
:target: https://github.com/openwisp/django-rest-framework-gis/actions/workflows/ci.yml
.. |Coverage Status| image:: https://coveralls.io/repos/openwisp/django-rest-framework-gis/badge.svg
:target: https://coveralls.io/r/openwisp/django-rest-framework-gis
.. |Requirements Status| image:: https://img.shields.io/librariesio/release/github/openwisp/django-rest-framework-gis
Expand Down
2 changes: 1 addition & 1 deletion requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ psycopg2
django-filter>=2.0
contexttimer
# QA checks
openwisp-utils[qa]~=1.0.0
openwisp-utils[qa]~=1.0.5
packaging~=20.4
8 changes: 4 additions & 4 deletions rest_framework_gis/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ def filter_queryset(self, request, queryset, view):
return queryset.order_by(GeometryDistance(filter_field, point))

def get_schema_operation_parameters(self, view):
params = super().get_schema_operation_parameters(view)
params.append(
return [
*super().get_schema_operation_parameters(view),
{
"name": self.order_param,
"required": False,
Expand All @@ -306,5 +306,5 @@ def get_schema_operation_parameters(self, view):
},
"style": "form",
"explode": False,
}
)
},
]
28 changes: 18 additions & 10 deletions rest_framework_gis/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ def __init__(self, *args, **kwargs):
default_id_field = primary_key
meta.id_field = getattr(meta, 'id_field', default_id_field)

if not hasattr(meta, 'geo_field') or not meta.geo_field:
raise ImproperlyConfigured("You must define a 'geo_field'.")
if not hasattr(meta, 'geo_field'):
raise ImproperlyConfigured(
"You must define a 'geo_field'. "
"Set it to None if there is no geometry."
)

def check_excludes(field_name, field_role):
"""make sure the field is not excluded"""
Expand All @@ -93,7 +96,9 @@ def add_to_fields(field_name):
meta.fields += additional_fields

check_excludes(meta.geo_field, 'geo_field')
add_to_fields(meta.geo_field)

if meta.geo_field is not None:
add_to_fields(meta.geo_field)

meta.bbox_geo_field = getattr(meta, 'bbox_geo_field', None)
if meta.bbox_geo_field:
Expand Down Expand Up @@ -128,12 +133,15 @@ def to_representation(self, instance):
# must be "Feature" according to GeoJSON spec
feature["type"] = "Feature"

# required geometry attribute
# MUST be present in output according to GeoJSON spec
field = self.fields[self.Meta.geo_field]
geo_value = field.get_attribute(instance)
feature["geometry"] = field.to_representation(geo_value)
processed_fields.add(self.Meta.geo_field)
# geometry attribute
# must be present in output according to GeoJSON spec
if self.Meta.geo_field:
field = self.fields[self.Meta.geo_field]
geo_value = field.get_attribute(instance)
feature["geometry"] = field.to_representation(geo_value)
processed_fields.add(self.Meta.geo_field)
else:
feature["geometry"] = None

# Bounding Box
# if auto_bbox feature is enabled
Expand Down Expand Up @@ -211,7 +219,7 @@ def unformat_geojson(self, feature):
"""
attrs = feature["properties"]

if 'geometry' in feature:
if 'geometry' in feature and self.Meta.geo_field:
attrs[self.Meta.geo_field] = feature['geometry']

if self.Meta.id_field and 'id' in feature:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.24 on 2024-02-28 22:57

import django.contrib.gis.db.models.fields
from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('django_restframework_gis_tests', '0003_schema_models'),
]

operations = [
migrations.AlterField(
model_name='boxedlocation',
name='geometry',
field=django.contrib.gis.db.models.fields.GeometryField(srid=4326),
),
migrations.AlterField(
model_name='locatedfile',
name='geometry',
field=django.contrib.gis.db.models.fields.GeometryField(srid=4326),
),
migrations.AlterField(
model_name='location',
name='geometry',
field=django.contrib.gis.db.models.fields.GeometryField(srid=4326),
),
]
14 changes: 10 additions & 4 deletions tests/django_restframework_gis_tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class BaseModel(models.Model):
name = models.CharField(max_length=32)
slug = models.SlugField(max_length=128, unique=True, blank=True)
timestamp = models.DateTimeField(null=True, blank=True)
geometry = models.GeometryField()

class Meta:
abstract = True
Expand All @@ -44,15 +43,22 @@ def save(self, *args, **kwargs):
super().save(*args, **kwargs)


class Location(BaseModel):
class BaseModelGeometry(BaseModel):
class Meta:
abstract = True

geometry = models.GeometryField()


class Location(BaseModelGeometry):
pass


class LocatedFile(BaseModel):
class LocatedFile(BaseModelGeometry):
file = models.FileField(upload_to='located_files', blank=True, null=True)


class BoxedLocation(BaseModel):
class BoxedLocation(BaseModelGeometry):
bbox_geometry = models.PolygonField()


Expand Down
8 changes: 8 additions & 0 deletions tests/django_restframework_gis_tests/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
MultiLineStringModel,
MultiPointModel,
MultiPolygonModel,
Nullable,
PointModel,
PolygonModel,
)
Expand Down Expand Up @@ -185,6 +186,13 @@ class Meta:
fields = ['name', 'slug', 'id']


class NoGeoFeatureMethodSerializer(gis_serializers.GeoFeatureModelSerializer):
class Meta:
model = Nullable
geo_field = None
fields = ['name', 'slug', 'id']


class PointSerializer(gis_serializers.GeoFeatureModelSerializer):
class Meta:
model = PointModel
Expand Down
10 changes: 10 additions & 0 deletions tests/django_restframework_gis_tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,16 @@ def test_geometry_serializer_method_field_none(self):
self.assertEqual(response.data['properties']['name'], 'None value')
self.assertEqual(response.data['geometry'], None)

def test_geometry_serializer_method_field_nogeo(self):
nullable = Nullable.objects.create(name='No geometry value')
nullable_loaded = Nullable.objects.get(pk=nullable.id)
self.assertEqual(nullable_loaded.name, "No geometry value")
url = reverse('api_geojson_nullable_details_nogeo', args=[nullable.id])
response = self.client.generic('GET', url, content_type='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['properties']['name'], 'No geometry value')
self.assertEqual(response.data['geometry'], None)

def test_nullable_empty_geometry(self):
empty = Nullable(name='empty', geometry='POINT EMPTY')
empty.full_clean()
Expand Down
5 changes: 5 additions & 0 deletions tests/django_restframework_gis_tests/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
views.geojson_nullable_details,
name='api_geojson_nullable_details',
),
path(
'geojson_nogeo/<int:pk>/',
views.geojson_nullable_details_nogeo,
name='api_geojson_nullable_details_nogeo',
),
path(
'geojson_hidden/<int:pk>/',
views.geojson_location_details_hidden,
Expand Down
10 changes: 10 additions & 0 deletions tests/django_restframework_gis_tests/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
LocationGeoFeatureSlugSerializer,
LocationGeoFeatureWritableIdSerializer,
LocationGeoSerializer,
NoGeoFeatureMethodSerializer,
NoneGeoFeatureMethodSerializer,
PaginatedLocationGeoSerializer,
PolygonModelSerializer,
Expand Down Expand Up @@ -167,6 +168,15 @@ class GeojsonLocationDetailsNone(generics.RetrieveUpdateDestroyAPIView):
geojson_location_details_none = GeojsonLocationDetailsNone.as_view()


class GeojsonNullableDetailsNoGeo(generics.RetrieveUpdateDestroyAPIView):
model = Nullable
serializer_class = NoGeoFeatureMethodSerializer
queryset = Nullable.objects.all()


geojson_nullable_details_nogeo = GeojsonNullableDetailsNoGeo.as_view()


class GeojsonLocationSlugDetails(generics.RetrieveUpdateDestroyAPIView):
model = Location
lookup_field = 'slug'
Expand Down

0 comments on commit dd48b10

Please sign in to comment.