Set serializer geo_field as PointField from another model - Django

北战南征 提交于 2019-12-08 07:26:59

问题


I have two models and need to serialize Article as Geojson by setting the geo_field attribute as point from the Location model. After following the solution given here I get the error:

Got AttributeError when attempting to get a value for field `point` on serializer `ArticleSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Article` instance.
Original exception text was: 'ManyRelatedManager' object has no attribute 'point'.

Here are my models:

class Location(models.Model):
    city = models.CharField(max_length=200)
    point = models.PointField(srid=4326)
    objects = models.GeoManager()

class Article(models.Model):
    locations = models.ManyToManyField(Location)
    article_title = models.CharField(max_length=200)

    @property
    def point(self):
    return self.locations.point

And my serializer:

class ArticleSerializer(GeoFeatureModelSerializer):
point = GeometryField()

class Meta:
    model = Article
    geo_field = "point"
    id_field = False
    fields = ('pub_date', 'point',)

Any help appreciated. I've been trying to find a solution to this for ages with little success!

UPDATE!

Ok, getting somewhere with this. I created a LocationSerializer and reference this in ArticleSerializer. These now look something like this:

class LocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Location
        geo_field = "point"
        id_field = False
        fields = ('point',)

class ArticleSerializer(GeoFeatureModelSerializer):
    locations = LocationSerializer(many=True)       
    class Meta:
        model = Article
        geo_field = "locations"
        id_field = False
        fields = ('pub_date', 'locations',)

The output is closer to what I want...but still a bit obscure in construct:

{  
    "type":"FeatureCollection",
    "features":[  
        {  
            "type":"Feature",
            "geometry":[  
                {  
                    "point":{  
                        "type":"Point",
                        "coordinates":[  
                            -2.200337956118645,
                            53.48316423741371
                        ]
                    }
                },
                {  
                    "point":{  
                        "type":"Point",
                        "coordinates":[  
                            0.041198730463564,
                            51.51002453017606
                        ]
                    }
                }
            ],
            "properties":{  
                "pub_date":"2015-04-06T20:38:59Z"
            }
        }
    ]
}

UPDATE!

The format I require is:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "time": "2013-01-22 08:42:26+01"
            },
            "geometry": {
                "type": "Point",
                "coordinates": [
                    7.582512743,
                    51.933292258,
                    1
                ]
            }
        },

回答1:


The issue is that your point property on the Article model is referring to self.locations which is a ManyToManyField. You are calling self.locations.point as though self.locations is a ForeignKey which is why you are getting your error.

'ManyRelatedManager' object has no attribute 'point'.

Means that self.locations is returning a ManyRelatedManager, which makes sense for a ManyToManyField. Since you are only expecting a single object, that means you need to make one of two changes

  1. You really were looking to have locations be a ForeignKey, which would mean your point property is correct.
  2. You are actually expecting multiple locations for an Article, and your point property should actually be returning a list of points.

    return [location.point for location in self.locations]
    

If you are actually looking for multiple locations, you are also going to want to set many=True on your GeometryField on your serializer.




回答2:


Ok, the solution seems to be...don't do it the way I was attempting. I've got round the bulk of the problem by using vectorformats.DjangoWStyle (just search google) to deal with searializing geojson from two models. Also, attempting a reverse relationship to achives this will lead to a world of misery. Instead I added the ManyToManyField on Location model, referencing the Article model.



来源:https://stackoverflow.com/questions/30062905/set-serializer-geo-field-as-pointfield-from-another-model-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!