I have the following models:
class Geofence(models.Model):
id = models.IntegerField(default=0, primary_key=True)
name = models.CharField(max_length=200, default="Geofence", blank=False)
lat = models.DecimalField(default=0, decimal_places=6, max_digits=10, blank=False)
long = models.DecimalField(default=0, decimal_places=6, max_digits=10, blank=False)
radius = models.IntegerField(default=10, blank=False)
def __str__(self):
return "Geofence: " + str(self.name);
class Checkpoint(models.Model):
id = models.IntegerField(default=0, primary_key=True)
name = models.CharField(max_length=200, default="Geofence", blank=False)
geofence = models.ForeignKey(Geofence, related_name='geofence')
lat = models.DecimalField(default=0, decimal_places=6, max_digits=10, blank=False)
long = models.DecimalField(default=0, decimal_places=6, max_digits=10, blank=False)
trip_id = models.IntegerField(default=0, blank=False)
enter_time = models.DateTimeField("Enter Time", blank=False)
start_time = models.DateTimeField("Start Time", blank = True, null=True)
stop_time = models.DateTimeField("Stop Time", blank= True, null = True)
and their respective serializers:
class GeofenceSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(min_value=0)
name = serializers.CharField()
lat = serializers.DecimalField(max_digits=10, decimal_places=6, coerce_to_string=False)
long = serializers.DecimalField(max_digits=10, decimal_places=6, coerce_to_string=False)
radius = serializers.IntegerField(min_value=0)
class Meta:
model = Geofence
fields = ('id', 'name','lat', 'long', 'radius')
def create(self, valid_data):
return Geofence.objects.create(**valid_data)
def update(self, instance, valid_data):
instance.id = valid_data.get('id', instance.id)
instance.name = valid_data.get('name', instance.name)
instance.name = valid_data.get('lat', instance.lat)
instance.long = valid_data.get('long', instance.long)
instance.radius = valid_data.get('radius', instance.radius)
instance.save()
class CheckpointSerializer(serializers.ModelSerializer):
lat = serializers.DecimalField(max_digits=10, decimal_places=6, coerce_to_string=False)
long = serializers.DecimalField(max_digits=10, decimal_places=6, coerce_to_string=False)
enter_time = serializers.DateTimeField()
start_time =serializers.DateTimeField()
geofence = serializers.SlugRelatedField(many=False, slug_field="id", read_only=True)
class Meta:
model = Checkpoint
fields = ('trip_id', 'geofence', 'start_time', 'stop_time', 'lat', 'long', 'enter_time')
I am taking datetimes from a slider and making an ajax call to get the relevant data. The server responds with a 500 error. Specifically, the error "KeyError: geofence"
Here is the view that is called:
class ResultsView(APIView):
model = Checkpoint
serializer_class = CheckpointSerializer
def get(self, request, start, end):
begin_date = parse_datetime(request.GET["start"])
end_date = parse_datetime(request.GET["end"])
ids = Checkpoint.objects.filter(start_time__range=(begin_date,end_date)).filter(stop_time__range=(begin_date,end_date)).distinct().values('trip_id', 'lat', 'long', 'enter_time')
serializer = CheckpointSerializer(ids, many=True)
return Response(serializer.data)
def post(self, request, format=None):
request.data["id"] = uuid.uuid4().int & (1<<8)-1
serializer = CheckpointSerializer(data= request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.error)
and angular call:
$http.get("http://127.0.0.1:8000/traffic/get/?end=" + $scope.endDateTime + "&format=json&search=Search&start=" + $scope.startDateTime)
.then(function(response) {
console.log("Response: " + response.data)
$scope.data = response.data;
});
I believe the issue is the foreign key in the serializer:
geofence = serializers.SlugRelatedField(many=False, slug_field="id", read_only=True)
Is this the correct way to serialize a foreign key in django rest framework? If not, would someone provide an example?
For this particular issue, I solved it by using the source argument in a character field to represent a foreign key as opposed to a related field. The correct serializer entry in this case is:
geofence = serializers.CharField(source='geofence.id', read_only=True)
class Meta:
model = Checkpoint
fields = ('geofence', 'start_time', 'lat', 'long', 'enter_time')
I used this in the Checkpoint table as a checkpoint is a geofence instead of incorrectly putting the foreign key in the geofence table in the original post. The field name is simply listed in the class meta. The class meta being necessary because the serializer is a model serializer.
Do you mean this? Specifying nested serialization
There is an simple example:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
depth = 1 # You need only add this sentence.
The result is something like this:
[
{
"id": 1,
"priority": 10,
"role": {
"id": 1,
"department": "researcher"
}
}
]
However, you can get all the fields of the ForeignKey. I don't know how to get some of the fields of the ForeignKey.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With