使用 Django 在多边形中实现点搜索
Implementing point search in a polygon using Django
在 Django 中实现我的应用程序时遇到了一些困难。应用应该做什么:
- 接受交付区域并将其保存为一组坐标;
- 接受有关送货区域的快递数据;
- 接受送货地点坐标和returns快递数据和送货区域ID。
我解决了两点,但是最后一点有问题。我需要知道送货地点是否在送货区内。我在 Python shell:
中找到了解决这个问题的方法
from django.contrib.gis.geos import GEOSGeometry
p = GEOSGeometry(location, srid=4326)
DeliveryZone.objects.filter(coordinates__contains=p)
但我不知道如何在我的应用程序中实现它。
models.py
from django.contrib.gis.db import models
class DeliveryZone(models.Model):
coordinates = models.MultiPolygonField(srid=4326)
def __str__(self):
return f"#{self.id}"
class Courier(models.Model):
delivery_zone = models.ForeignKey(DeliveryZone, on_delete=models.PROTECT)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def __str__(self):
return f"#{self.id} {self.last_name}"
class Delivery(models.Model):
location = models.PointField(srid=4326)
def __str__(self):
return f"#{self.id}"
views.py
from django.contrib.gis.geos import GEOSGeometry
from rest_framework import viewsets
from .serializers import DeliveryZoneSerializer, CourierSerializer, DeliverySerializer
from .models import DeliveryZone, Courier, Delivery
class DeliveryZoneViewSet(viewsets.ModelViewSet):
queryset = DeliveryZone.objects.all()
serializer_class = DeliveryZoneSerializer
class CourierViewSet(viewsets.ModelViewSet):
queryset = Courier.objects.all()
serializer_class = CourierSerializer
class DeliveryViewSet(viewsets.ModelViewSet):
queryset = Delivery.objects.all()
serializer_class = DeliverySerializer
如有必要,我可以提供更多信息。
最佳做法是为此使用 a manager。然后在 django rest 框架中,你将挂钩到 get_queryset
并删除 queryset
.
伪代码。
from rest_framework.generics import ListAPIView
class DeliveryViewSet(ListAPIView):
serializer_class = DeliverySerializer
def get_queryset(self):
# put a ref to zone_id in your url
zone_id = self.kwargs.get('zone_id')
zone_instance = get_object_or_404(DeliveryZone, id=zone_id)
# implement filter_by_zone in your manager
return Delivery.objects.filter_by_zone(zone_instance).all()
在 Django 中实现我的应用程序时遇到了一些困难。应用应该做什么:
- 接受交付区域并将其保存为一组坐标;
- 接受有关送货区域的快递数据;
- 接受送货地点坐标和returns快递数据和送货区域ID。
我解决了两点,但是最后一点有问题。我需要知道送货地点是否在送货区内。我在 Python shell:
中找到了解决这个问题的方法from django.contrib.gis.geos import GEOSGeometry
p = GEOSGeometry(location, srid=4326)
DeliveryZone.objects.filter(coordinates__contains=p)
但我不知道如何在我的应用程序中实现它。
models.py
from django.contrib.gis.db import models
class DeliveryZone(models.Model):
coordinates = models.MultiPolygonField(srid=4326)
def __str__(self):
return f"#{self.id}"
class Courier(models.Model):
delivery_zone = models.ForeignKey(DeliveryZone, on_delete=models.PROTECT)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def __str__(self):
return f"#{self.id} {self.last_name}"
class Delivery(models.Model):
location = models.PointField(srid=4326)
def __str__(self):
return f"#{self.id}"
views.py
from django.contrib.gis.geos import GEOSGeometry
from rest_framework import viewsets
from .serializers import DeliveryZoneSerializer, CourierSerializer, DeliverySerializer
from .models import DeliveryZone, Courier, Delivery
class DeliveryZoneViewSet(viewsets.ModelViewSet):
queryset = DeliveryZone.objects.all()
serializer_class = DeliveryZoneSerializer
class CourierViewSet(viewsets.ModelViewSet):
queryset = Courier.objects.all()
serializer_class = CourierSerializer
class DeliveryViewSet(viewsets.ModelViewSet):
queryset = Delivery.objects.all()
serializer_class = DeliverySerializer
如有必要,我可以提供更多信息。
最佳做法是为此使用 a manager。然后在 django rest 框架中,你将挂钩到 get_queryset
并删除 queryset
.
伪代码。
from rest_framework.generics import ListAPIView
class DeliveryViewSet(ListAPIView):
serializer_class = DeliverySerializer
def get_queryset(self):
# put a ref to zone_id in your url
zone_id = self.kwargs.get('zone_id')
zone_instance = get_object_or_404(DeliveryZone, id=zone_id)
# implement filter_by_zone in your manager
return Delivery.objects.filter_by_zone(zone_instance).all()