【问题标题】:GeoDjango serialize GeoJSON skipping 'id' fieldGeoDjango 序列化 GeoJSON 跳过“id”字段
【发布时间】:2016-01-01 13:50:46
【问题描述】:

我一直在使用 Geo-Django GeoJSON serializer,这样我就可以从 PostGIS 数据库中检索一些对象并将它们显示在 OpenLayers 地图上。

我正在通过以下方式获取要显示的对象:

gqs = self.model.objects.filter(point__distance_lte=(pnt, long(dist)))
type(gqs)
<class 'django.contrib.gis.db.models.query.GeoQuerySet'>

并且地理对象按预期包含所有模型字段:

self.model._meta.get_fields()
(<django.db.models.fields.AutoField: id>,
<django.db.models.fields.CharField: name>, 
<django.db.models.fields.SlugField: name_slug>, 
<django.db.models.fields.CharField: contact>, 
<django.db.models.fields.CharField: address>, 
<django.db.models.fields.CharField: postcode>, 
<django.db.models.fields.EmailField: email>, 
<django.db.models.fields.CharField: fax>, 
<django.db.models.fields.CharField: tel>, 
<django.db.models.fields.CharField: tel1>, 
<django.db.models.fields.CharField: tel_fax>, 
<django.db.models.fields.URLField: url>, 
<django.db.models.fields.CharField: wardlabel>, 
<django.db.models.fields.DecimalField: lon>, 
<django.db.models.fields.DecimalField: lat>, 
<django.db.models.fields.IntegerField: easting>, 
<django.db.models.fields.IntegerField: northing>, 
<django.db.models.fields.DateField: first_entered>, 
<django.db.models.fields.DateField: updated>, 
<django.contrib.gis.db.models.fields.PointField: point>)

包括id值...

(Pdb) gqs[0].id
5

然后我以最简单的方式将 GeoQuerySet 传递给 GeoJSON 序列化程序:

gqs_serialized = serialize('geojson', gqs)

并获得输出:

gqs_serialized
u'{"type": "FeatureCollection", 
  "crs": {
    "type": "name", 
    "properties": {"name": "EPSG:4326"}}, 
    "features": [
    {"geometry": {"type": "Point", "coordinates": [-0.19038, 51.490657]}, "type": "Feature", 
    "properties": {
      "tel1": null, 
      "fax": null, 
      "tel": null, 
      "name": "some club", 
      "url": null, 
      "wardlabel": "Redcliffe", 
      "lon": "-0.190380", 
      "updated": null, 
      "first_entered": "2013-12-01", 
      "contact": "some name", 
      "name_slug": "some club slug", 
      "postcode": "SW5 0JE", 
      "easting": 525732, 
      "address": "Some Address, London", 
      "lat": "51.490657", 
      "tel_fax": null, 
      "email": null, 
      "northing": 178409}},
     {"geometry": {"type": "Point", "coordinates": [-0.137183, 51.495597]}, "type": "Feature", 
    "properties": { etc...

除了模型中的“id”字段(AutoField)之外,所有内容都存在。我想将 id 值用作网页中的 div id 值,并且当我认为应该已经可用时,我真的不想创建另一个唯一 id(即组合 lon/lat 值)。

缺少的“id”字段发生了什么?

【问题讨论】:

    标签: django serialization geojson geodjango


    【解决方案1】:

    就输出必须与specs 兼容而言,库存序列化程序会忽略不支持的字段。但是,您可以制作自己的序列化程序:

    # yourapp/geojson_serializer.py
    from django.contrib.gis.serializers import Serializer as GeoJSONSerializer
    
    class Serializer(GeoJSONSerializer):
        def get_dump_object(self, obj):
            data = super(Serializer, self).get_dump_object(obj)
            # Extend to your taste
            data.update(id=obj.pk)
            return data
    

    settings.py 中启用您的新序列化程序:

    SERIALIZATION_MODULES = {
            "custom_geojson": "yourapp.geojson_serializer",
    }
    

    然后在你的代码中使用它:

    from django.core import serializers
    data = serializers.serialize('custom_geojson', some_model)
    

    【讨论】:

    • 感谢您,简洁明了的解释。那就是说我显然不完全理解它,因为我还没有能够实现它。作为快速修复,我使用了django-geojson 模块,它序列化包含 id 字段的 GeoJSON。如果你能给我一个应该如何调用 GeoJSONWithIdsSerializer 的例子,我将不胜感激。另外我认为 Serializer 不再存在(?)我只能使用:from django.core.serializers import serialize as GeoJSONSerializer
    • 设法通过再次更改导入语句来使其工作:from django.core import serializers GeoJSONSerializer = serializers.get_serializer("geojson") 并将其实例化为:gqs_serialized = GeoJSONWithIdsSerializer().serialize(gqs)
    • 这个post 也有帮助。
    • @jayuu,对不起,我已经扩展了答案。
    • 完全没问题。我已经将自定义类放在了我的 views.py 文件中,但这更干净,我也期待更多 Pythonic!非常感谢您的帮助。
    【解决方案2】:

    我也可以通过使用来自 @jayuu 的输入来解决这个问题。对于新读者 对此问题感兴趣,我发布完整的解决方案:

    #myapp/geojson_serializer.py
    from django.core import serializers
    
    GeoJSONSerializer = serializers.get_serializer("geojson")
    
    class Serializer(GeoJSONSerializer):
        def get_dump_object(self, obj):
            data = super(Serializer, self).get_dump_object(obj)
            # Extend to your taste
            data.update(id=obj.pk)
            return data
    

    然后,为了在我的视图中使用它,我只是导入了该函数,因为我对注册我的序列化程序没有兴趣

    #myapp/views.py
    from .geojson_serializer import Serializer
    
    def MapDataView(request):
        geojson_serializer = Serializer()
        geojson_serializer.serialize(some_queryset)
        data = geojson_serializer.getvalue()
        return HttpResponse(data, content_type='json')
    

    你有它。

    【讨论】:

      【解决方案3】:

      我解决此问题的一种方法是要求它序列化“pk”字段,该字段按预期工作。

      gqs_serialized = serialize('geojson', gqs, fields=('pk', ))
      

      【讨论】:

        猜你喜欢
        • 2016-02-16
        • 1970-01-01
        • 1970-01-01
        • 2017-03-17
        • 2021-04-22
        • 1970-01-01
        • 1970-01-01
        • 2015-07-01
        • 1970-01-01
        相关资源
        最近更新 更多