2017-02-23 53 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格式。