Я пытаюсь выполнить агрегирование модели (Ответить) по географическому признаку c Площадь (Hexgrid_10km2). Аналогично SQL 'group by'. Я использую .values (Hexgrid_10km), чтобы сделать это. Затем я комментирую некоторые цифры на это. Я получаю следующую ошибку в сериализации для geo json:
У объекта 'dict' нет атрибута 'hexgrid_10km2'
Но у ответа есть поле с именем 'hexgrid_10km2'.
Я не могу понять это. Я пробовал другие способы сериализации в stackoverflow, но всегда, похоже, получаю ошибку. Кто-нибудь знает, что я делаю не так? Большое спасибо !!
Я использую djangorestframework-gis
Модели
class Hexgrid_10km2(models.Model):
lng = models.FloatField()
lat = models.FloatField()
polygon = models.MultiPolygonField(srid=4326)
centroid = models.PointField(default=Point(0,0), srid=4326)
def __str__(self):
return f'lng: { self.lng } lat: {self.lat }'
class Animal (models.Model):
name = models.CharField(max_length=200)
class Reply(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
reply_date = models.DateTimeField()
animal = models.ForeignKey(Animal, on_delete=models.CASCADE)
ability = models.IntegerField(default = 0)
hexgrid_10km2 = models.ForeignKey(Hexgrid_10km2, on_delete=models.CASCADE, null=True, blank=True)
@property
def polygon_10km2(self):
return self.hexgrid_10km2.polygon
Просмотры
from rest_framework.views import APIView
from rest_framework.response import Response
from.models import Animal, Reply, Hexgrid_10km2
from django.db.models import Avg, Sum
class ReplyHeatmapAPIView(APIView):
def get(self, request, pk):
animal = get_object_or_404(Animal, pk=pk)
relevant = Reply.objects.filter(animal=animal)
most_recent = relevant.filter(
reply_date=Subquery(
(Reply.objects
.filter(user=OuterRef('user'))
.values('user')
.annotate(most_recent=Max('reply_date'))
.values('reply_date')[:1]
)
)
final = most_recent.values('hexgrid_10km2')
.annotate(average_ability=Avg('ability'), sum_ability=Sum('ability'))
serializer = ReplyHeatmapSerializer(final, many=True)
return Response(serializer.data)
Сериализатор
from rest_framework_gis.fields import GeometrySerializerMethodField
from rest_framework_gis.serializers import GeoFeatureModelSerializer
class ReplyHeatmapSerializer(GeoFeatureModelSerializer):
""" A class to serialize hex polygons as GeoJSON compatible data """
average_ability = serializers.FloatField()
sum_ability = serializers.FloatField()
polygon = GeometrySerializerMethodField()
def get_polygon(self, obj):
return obj.hexgrid_10km2.polygon
class Meta:
model = Reply
geo_field = 'polygon'
depth = 1
id_field = False
fields = ('id', 'average_abilty', 'sum_ability')
Traceback
Traceback (most recent call last):
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\karate2\animals\api\views.py", line 109, in get
return Response(serializer.data)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework_gis\serializers.py", line 20, in data
return super(ListSerializer, self).data
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework\serializers.py", line 260, in data
self._data = self.to_representation(self.instance)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework_gis\serializers.py", line 28, in to_representation
("features", super(GeoFeatureModelListSerializer, self).to_representation(data))
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework\serializers.py", line 677, in to_representation
return [
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework\serializers.py", line 678, in <listcomp>
self.child.to_representation(item) for item in iterable
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework_gis\serializers.py", line 116, in to_representation
feature["geometry"] = field.to_representation(geo_value)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework_gis\fields.py", line 101, in to_representation
value = super(GeometrySerializerMethodField, self).to_representation(value)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\venv\lib\site-packages\rest_framework\fields.py", line 1905, in to_representation
return method(value)
File "C:\Users\anton\OneDrive\Documents\django\karate-project-2.2\karate2\animals\api\serializers.py", line 61, in get_polygon
return obj.hexgrid_10km2.polygon
AttributeError: 'dict' object has no attribute 'hexgrid_10km2'
ОБНОВЛЕНИЕ Измененный код. Причина, по которой я фильтрую по ответам, а не по Hexgrid, заключается в том, что пользователи могут делать несколько ответов для одного и того же животного. Поэтому мне нужно отфильтровать самый последний ответ, который пользователь сделал для определенного животного. Я понимаю, что .values () не предназначен для группировки, но как еще я могу это сделать? Я думал о группировке по шестнадцатеричной сетке, но не смог, так как даже создание запроса для получения первого ответа на пользователя потребовалось мне много времени, чтобы выяснить.