Django Rest Framework general model serializer
blog.hipwerk.com
blog.hipwerk.com
You can actually use Spyne with Django as well[3] (and Spyne has a "general model serializer" that can be used with a lot less boilerplate than what's shown here).
Spyne supports a lot of protocols as well as persisting to a relational database via SQLAlchemy.
Disclaimer: I'm the author of spyne.
[1]: http://spyne.io
[2]: https://pypi.python.org/pypi/Flask-Spyne
[3]: https://github.com/arskom/spyne/tree/master/examples/django/...
Besides, after working a lot with REST webservices and AngularJS, i don't know if serializing child objects is really a good idea vs just getting the id and then using the api endpoint for the specific children separately. Having child objects serialized creates problems when doing PUT/UPDATE requests and you can also end up with fairly large sets of JSON. Of course doing dozens of requests instead (especially for lists) is also not the best of ideas, so i am not really sure how others handle this ?
But DRF adds lots of extra functionality. Even with DRF it's as simple as adding:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
to get full automatic serialization of a model.> I don't know if serializing child objects is really a good idea
Depends on the specific case. For internal APIs I tend to create endpoints that give a view what it needs in a single request.
from django.core import serializers
print serializers.serialize("json", StockCount.objects.all()[:2])
>> [{"fields": {"timestamp": "1900-01-02T00:00:00Z", "version": 0, "item_instance": null, "item_model": 408, "stock_level": 999, "location": 2}, "model": "stocklevels.stockcount", "pk": 1}, {"fields": {"timestamp": "1900-01-02T00:00:00Z", "version": 0, "item_instance": null, "item_model": 409, "stock_level": 999, "location": 2}, "model": "stocklevels.stockcount", "pk": 2}]As far as I know DRF does not support PUT/UPDATE operations for nested serializers. But there are cases when you just need to read. Like getting an activity feed which can't be modified directly by the users. I think if you have a good caching system it's better to return all the data for one request instead of creating new requests to get details about each entity.
We then have separate, traditional REST endpoints for updates/creates and incremental updates of the larger object.
This is an edge case for something called Django Content Types. It's basically a way to handle some sort of polymorphism in a table.
Let's say you have a table called activity feed like in this example. Whether the items in the feed are images, blog posts, or status updates they're all going to have something in common and you'll have endpoints that should link any relevant tables and combine them. So you'd have an activity table and it would have a column for content_type and then content_object_id. Content type is basically just a reference to another DB table (blog or status update) with more info on this activity and content_object_id is the actual id of the row in that table.
I've used Symfony, Laravel, and pretty much every other trendy PHP framework and nothing comes close to the ease of building APIs that is inherent in Django Rest Framework.
This is just a very specific use case that you normally have to handle using it's own custom class. This just shows a way you can have DRF serialize it like a normal object without issue.
I think it's a really cool concept if you think of it as more of a Lens. The so-called serializer lets you declare properties of "fields", and these properties will influence both the native-to-ORM conversion, as well as the ORM-to-native conversion.
* Write the `create()` and/or `update()` methods explicitly on the serializer class.
* Push logic into the model and model manager where possible and only have the serializer `.save()` as a thin layer on top of that.
That way a serializer class still has all the behavior it needs to map both ways between persisted objects and their corresponding native python representations, but you still have a well separated model API.
The "deserializer"'s job is to perform validation and type coercion of incoming requests. It returns a "native" dictionary, which the application code then saves to ORM.
The "serializer" is basically a presentation layer. It calls out to other nested serializers [this is awesome!], and it throws in convenience-fields that make the API response easier to consume.
This pattern makes it a little bit less "magical", and it's easier to distinguish between the API's "incoming" behavior and its "outgoing" behavior.
Therefore, for an ongoing project I've implemented something along the lines of your idea (if I got that correctly), by describing API-Layer models in terms of properties, which are just named sets of pure lambdas. The most general property only requires a single one to compute the property value from an input business-model.
This allows for some very nice things, especially with regards to API-level functionality like support for nested ?expand=, ?only=, and such niceties.
Oh, and try customizing error messages or providing customer error conditions... It's just not fun. I think this is the weakest part of DRF.
Just looking through largish DRF codebase, I'm not sure there are many places I could use this, thought it seems like a good idea if your code has a lot of these scenarios.