#python #django #django-rest-framework #relationship
Вопрос:
я новичок в django и перешел с symfony. я хочу попробовать создать простую связь между 2 моделями в django-rest-фреймворке и получить для них apiview. но я не могу понять, почему сериализаторы не обрабатывают отношения между этими 2 моделями.
мои модели в models.py
from django.contrib.gis.db import models
from django.contrib.gis.geos import Point
import uuid
class RequestLocation(models.Model):
gpslocation = models.PointField(srid=4326, geography=True, default=Point(0.0, 0.0))
gpslocationradius = models.IntegerField(default=5)
description = models.TextField(default='#')
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['created']
def __str__(self):
return self.id
class Shops(models.Model):
gpslocation = models.PointField(srid=4326, geography=True, default=Point(0.0, 0.0))
created = models.DateTimeField(auto_now_add=True)
requestlocations = models.ManyToManyField(RequestLocation, null=True, blank=True)
class Meta:
ordering = ['created']
def __str__(self):
return self.id
и мои сериализаторы в serializers.py:
from rest_framework_gis.serializers import GeoFeatureModelSerializer
from .models import RequestLocation, Shops
class RequestLocationSerializer(GeoFeatureModelSerializer):
class Meta:
model = RequestLocation
geo_field = 'gpslocation'
auto_bbox = True
id_field = 'id'
fields = ['id', 'gpslocation', 'gpslocationradius', 'description']
class ShopsSerializer(GeoFeatureModelSerializer):
requestlocations = RequestLocationSerializer(read_only=True)
class Meta:
model = Shops
geo_field = 'gpslocation'
auto_bbox = True
id_field = 'id'
fields = ['id', 'gpslocation', 'requestlocations']
и views.py:
# RequestLocation view
@api_view(['GET', 'POST'])
def rl_list(request, format=None):
if request.method == 'GET':
rl = RequestLocation.objects.all()
serializer = RequestLocationSerializer(rl, many=True)
distance_filter_field = 'geometry'
filter_backends = (DistanceToPointFilter)
bbox_filter_include_overlapping = True
return Response(serializer.data)
elif request.method == 'POST':
serializer = RequestLocationSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])
def rl_detail(request, pk, format=None):
try:
rl = RequestLocation.objects.get(pk=pk)
except RequestLocation.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = RequestLocationSerializer(rl)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = RequestLocationSerializer(rl, data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
rl.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
# Shop view
@api_view(['GET', 'POST'])
def shp_list(request, format=None):
if request.method == 'GET':
shp = Brokers.objects.all()
serializer = ShopsSerializer(shp, many=True)
distance_filter_field = 'geometry'
filter_backends = (DistanceToPointFilter)
bbox_filter_include_overlapping = True
return Response(serializer.data)
elif request.method == 'POST':
serializer = ShopsSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])
def shp_detail(request, pk, format=None):
try:
shp = Shops.objects.get(pk=pk)
except RequestLocation.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = ShopsSerializer(shp)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = ShopsSerializer(shp, data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
shp.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
когда я удалю requestlocations = RequestLocationSerializer(read_only=True)
все, все будет в порядке, и я смогу публиковать и получать магазины. но когда эта строка возвращается, я получаю SkipField at /shp/
ошибку.
пожалуйста, веди меня.
Комментарии:
1. Так
requestlocations
как это коллекция объектов, попробуйте добавитьmany=True
такRequestLocationSerializer(read_only=True, many=True)