2017-02-23 55 views
1

我有一些模型是非常简单的在他们的关系:不能模拟数据序列GeoDjango内置到JSON传递回网站

class CesiumEntity(models.Model): 
    be_number = models.CharField(max_length=100) #the number assigned to a foot print to distinguish 
    zone_id = models.ForeignKey('ZoneEntity', null=True, blank=True) 
    sensor = models.CharFIeld(max_length=100) # sensor this entity is from 
    .... 

class ZoneEntity(models.Model): 
    zone_number = models.CharField(max_length=100, primary_key=True) 
    #zone_number = models.CharField(max_length=100) 
    mpoly = models.PolygonField() #this should grow and shrink for the most representative one... 
    objects = models.GeoManager() 
    created_at=models.DateField(auto_now_add=True) 
    updated_at=models.DateField(auto_now=True) 

我想从数据他们作为加入:

object_list = ZoneEntity.objects.filter(cesiumentity__sensor__in=sensor).distinct('zone_number') 

它应该等效于SQL:

SELECT distinct(zone_number) FROM SWSITE_ZONEENTITY INNER JOIN SWSITE_CESIUMENTITY ON SWSITE_ZONEENTITY.zone_number = SWSITE_CESIUMENTITY.zone_id_id WHERE SWSITE_CESIUMENTITY.sensor = 'RADARSAT-2' 

因此,这给了我所有这些区域号码基于在UI上选择的传感器。这很好,每个zonenumber还有很多其他的东西(CesiumEntities)。所以我想把所有这些都作为一个json对象来发送回我的web界面。

像这样的事情

zoneEntity.ZoneNumber  # fromDB 
zoneEntity.mpoly (Geometry) # fromDB 
zoneEntity.cesiumEntities # list of all the cesiumentities with the 
          # zonenumber and with the sensor selected. 

理想的情况下,如果我能得到的东西,为的是自动拥有该数据序列化工作:

jdata =serialize('geojson', object_list, 
      geometry_field = 'mpoly'); 

但这种失败在许多方面......主要特性并且列表不存在或格式不正确。

所以我试图建立自己的对象发送回:(虽然我相信这是困难的方式):

returnData = [] 
secondData =[] 
object_list = ZoneEntity.objects.filter(cesiumentity__sensor__in=sensor).distinct('zone_number') 
print len(object_list) 
for ze in object_list: 
    second_list = CesiumEntity.objects.filter(zone_id = ze.zone_number) 
    returnData.append(ze.zone_number) 
    returnData.append(ze.mpoly) 
    for sl in second_list: 
     secondData.append(sl.sensor) 
     secondData.append(sl.resource_location) 
     secondData.append(sl.name) 
     secondData.append(sl.country_code) 
     secondData.append(sl.corner_coords) 
     secondData.append(sl.target_name) 
     secondData.append(sl.collection_date) 
    returnData.append(secondData) 

(不能完全确定上面是把事情以正确的方式准备好json序列化的格式) 所以我想将returnData序列化为json,这样我就可以将所有区域显示在地图上,然后单击时显示区域中的所有铯实体。到目前为止,当我尝试调用json.dumps我得到一个错误:

return HttpResponse(json.dumps({'data': returnData})) #was jdata 

结果:

raise TypeError(repr(o) + " is not JSON serializable") 
TypeError: <Polygon object at 0x10cb1a880> is not JSON serializable 

我没有看到这一点: http://www.django-rest-framework.org/tutorial/1-serialization/

我不能说如果这是我必须做,或者如果问题更简单,我只是误解了一些东西

我认为这可能是mpoly的一个问题,所以我抬头看了一些我TEMS(上mapping与匀称发现的东西)尝试,并得到任何地方(甚至对一个SO问题太:shapely mapping gives error on my geometry when serializing

+0

您是否尝试从'returnData'中删除'mpoly'来证明它是唯一的问题? – themanatuf

+0

其实很好的调用,mpoly是一个问题(它不能以任何格式序列化多边形,因为json.dumps需要mpoly是,我不知道如何做一个等效的geojson.dumps),但还有另一个问题与我的secondData.append(sl.collection_date),它将无法序列化或者(在注释掉mpoly后发现)。因此,就像mpoly和collection_date一样,它们需要比python对象更加字符串化。 – Codejoy

+0

也许你可以创建一个'JSONEncoder'类来检查对象类型,如果它是'Polygon'或'datetime',你可以返回对象的自定义表示。如果你需要另一种方式,你显然需要创建一个相应的解串器。你会像这样调用它'json.dumps(returnData,cls = CustomJSONEncoder)'https://docs.python.org/2/library/json.html#json.JSONEncoder – themanatuf

回答

1

您可以创建自己的一个名为serializers.py,利用rest_framework's serializers文件中的模型序列:

class ZoneEntitySerializer(serializers.ModelSerializer): 
    class Meta: 
     model = ZoneEntity 
     fields = ("the", "fields", "that", "you want", "serialized",) 

之后,您所制作的加入来看,保持

object_list = ZoneEntity.objects.filter(cesiumentity__sensor__in=sensor).distinct('zone_number') 

假设是你的情况是正确的。

最后创建响应:

res = ZoneEntitySerializer(object_list, many=True)(许多=真让我们的串行知道它会序列多个对象)

return HttpResponse(res.data)

现在的反应必须是JSON格式。