3353

Cross-table serialization Django REST Framework

Question:

I have two models with a many-to-many relationship and I am trying to return some geojson by using the Django REST Framework. The data I am trying to return is th pub_date and coordinates (represented by a PointField in GeoDjango). Everytime I try and return the geojson I get the error Field name 'city' is not valid for model 'Article'. I'm pretty new to django/geodjango and this is the first time I've used the Django REST Framework. I've gone through the docs but can't work out where I'm going wrong (or maybe even where to start).

Here my models and serializers.

models.py:

class Location(models.Model): city = models.CharField(max_length=200) country = models.CharField(max_length=200) continent = models.CharField(max_length=200) point = models.PointField(srid=4326) objects = models.GeoManager() def __unicode__(self): return u'%s' % (self.point) class Meta: db_table = 'location' class Article(models.Model): authors = models.ManyToManyField(Author) locations = models.ManyToManyField(Location, related_name='places') article_title = models.CharField(max_length=200, unique_for_date="pub_date") pub_date = models.DateTimeField('date published') article_keywords = ArrayField(ArrayField(models.CharField(max_length=20, blank=True), size=10), size=10,) title_id = models.CharField(max_length=200) section_id = models.CharField(max_length=200) def __unicode__(self): return u'%s %s %s' % (self.article_title, self.pub_date, self.article_keywords) class Meta: db_table = 'article'

serializers.py

class ArticleSerializer(serializers.ModelSerializer): places = serializers.PrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = Article fields = ('places')

And the output I would like:

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

Thanks in advance!

UPDATE! I managed to get somewhere with a raw SQL query embeded in a queryset but this is not not quite right:

serialize('geojson', Article.objects.raw(' select a.id, a.pub_date, al.location_id, l.point from article a join article_locations al on a.id = al.article_id join location l on al.location_id = l.id'), geometry_field = 'point', fields=('pub_date','locations',))

The result is this:

{ "type":"FeatureCollection", "crs":{ "type":"name", "properties":{ "name":"EPSG:4326" } }, "features":[ { "geometry":null, "type":"Feature", "properties":{ "pub_date":"2015-04-06T20:38:59Z", "locations":[ 3 ] } }

Answer1:

DRF serializers can do two things:

<ol><li>

Serialize complex data <em>(such as querysets)</em> to native Python datatypes

serializer = CommentSerializer(comment) serializer.data # {'email': u'leila@example.com', 'content': u'foo bar', 'created': datetime.datetime(2012, 8, 22, 16, 20, 9, 822774)} </li> <li>

Deserialize data from native Python datatypes

serializer = CommentSerializer(data=data) serializer.is_valid() # True serializer.validated_data # {'content': 'foo bar', 'email': 'leila@example.com', 'created': datetime.datetime(2012, 08, 22, 16, 20, 09, 822243)} </li> </ol>

In your case where

<blockquote>

All I want is to return all article pub_dates and their corresponding article coordinates lat/long's (from the pointField).

</blockquote>

You will have to do two things:

<ol><li>

Create a complex data structure using either an object, a list of objects or a queryset.

In your case this is pretty easy, you just need a queryset with all articles and with <a href="https://docs.djangoproject.com/en/1.7/ref/models/querysets/#prefetch-related" rel="nofollow">prefetched</a> locations in order to prevent unnecessary db hits for each location.

Article.objects.all().prefetch_related('locations')[:10] </li> <li>

Create a serializer which can serialize this queryset.

Since you have nested data structure <em>(one article can have many locations)</em> you better split this into two separate serializers.

The first one will know how to serialize locations only, and the second one will know how to serialize articles only, but it will use the first one for the article.locations serialization.

class LocationSerializer(serializers.ModelSerializer): class Meta: model = Location fields = ('point',) class ArticleSerializer(serializers.ModelSerializer): #this way we override the default serialization #behaviour for this field. locations = LocationSerializer(many=True) class Meta: model = Article fields = ('pub_date', 'locations') </li> </ol>

Finally you can combine 1 and 2 via a <a href="http://www.django-rest-framework.org/api-guide/viewsets/" rel="nofollow">ViewSet</a>

class ArticleViewSet(viewsets.ModelViewSet): serializer_class = ArticleSerializer #read about pagination in order to split this into pages queryset = Article.objects.all().prefetch_related('locations')[:10]

Recommend

  • Paste yanked block with `p` gets mixed with lines below
  • PHP: getting “SSA's” instead of “SSA's”
  • Error message: Illegal offset while accessing the array having a different structure than was seen s
  • How to enable httpsrc plug-in in my gstreamer?
  • Xpath Regex in PHP not working
  • Django Creating a Custom User with the Django Rest Framework
  • Removing per-panel unused factors in a bar chart
  • Django error 'unicode' object has no attribute 'objects'
  • Why won't this override of the Model.save() function in Django work?
  • How to distinguish field that requires null=True when blank=True is set in Django models?
  • How to not let setText crash/freeze my whole application? Even using SwingUtilities and Threads?
  • How can i use Django smart select to filter ManyToManyField?
  • Error Code: 1054. Unknown column
  • custom string delimiters stringtemplate-4
  • Insertion large number of Entities into SQL Server 2012 [duplicate]
  • Microsoft Excel Pivot miscalculation in Sum for positive and negative numbers
  • Django foreign key drop down
  • Why must we declare a variable name when adding a method to a struct in Golang?
  • Jackson Parser: ignore deserializing for type mismatch
  • Rails Find when some params will be blank
  • Row Count Is Returning the incorrect number using RaptureXML
  • Illegal mix of collations for operation for date/time comparison
  • Align navbar back button on right side
  • HTML download movie download link
  • Modifying destination and filename of gulp-svg-sprite
  • How to handle AllServersUnavailable Exception
  • How to model a transition system with SPIN
  • Release, debug version and Authorization Google?
  • VBA Convert delimiter text file to Excel
  • ORA-29908: missing primary invocation for ancillary operator
  • How to format a variable of double type
  • using conditional logic : check if record exists; if it does, update it, if not, create it
  • How to disable jQuery.jplayer autoplay?
  • Hits per day in Google Big Query
  • How to stop GridView from loading again when I press back button?
  • Bitwise OR returns boolean when one of operands is nil
  • sending mail using smtp is too slow
  • Busy indicator not showing up in wpf window [duplicate]
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?