Django Rest Framework: How to include linked resources in serializer response?

Question!

If write my own implementation of a ViewSet, and I want to return some objects, it's pretty simple:

class MyViewSet(ViewSet):
  def my_method(self, request):
    objects = MyModel.objects.all()
    return Response( MyModelSerializer(objects, many=True).data )

But let's say that I want to include the actual instance of another linked resource by a ForeignKey, instead of just an ID. For example:

class MyModel(Model):
  author = ForeignKey(MyOtherModel)
  ...

Is there a way to do something like this?

...
return Response( MyModelSerializer(objects, many=True, include='author').data )
By : daveslab


Answers

What you're looking for is nested relations. This is built into Django REST Framework. By explicitly defining your relation fields in your serializer you can specify many=True which will expand the related object.

From this example http://www.django-rest-framework.org/api-guide/relations/#example

class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = ('order', 'title', 'duration')

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = ('album_name', 'artist', 'tracks')

This can return:

{
    'album_name': 'The Grey Album',
    'artist': 'Danger Mouse',
    'tracks': [
        {'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
        {'order': 2, 'title': 'What More Can I Say', 'duration': 264},
        {'order': 3, 'title': 'Encore', 'duration': 159},
        ...
    ],
}
By : Soviut


You can use the depth meta attribute on your serializer.

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ('id', 'account_name', 'users', 'created')
        depth = 1

Specifying fields explicitly to control how they are serialized.

class AccountSerializer(serializers.ModelSerializer):
    url = serializers.CharField(source='get_absolute_url', read_only=True)
    groups = serializers.PrimaryKeyRelatedField(many=True)

    class Meta:
        model = Account 
By : agconti


std::ofstream fout("vector.txt");
fout << std::setprecision(10);

for(auto const& x : vector)
    fout << x << '\n';

Everything I changed had theoretically worse performance in your version of the code, but the std::endl was the real killer. std::vector::at (with bounds checking, which you don't need) would be the second, then the fact that you did not use iterators.

Why default-construct a std::ofstream and then call open, when you can do it in one step? Why call close when RAII (the destructor) takes care of it for you? You can also call

fout << std::setprecision(10)

just once, before the loop.

As noted in the comment below, if your vector is of elements of fundamental type, you might get a better performance with for(auto x : vector). Measure the running time / inspect the assembly output.


Just to point out another thing that caught my eyes, this:

for(l = 0; l < vector.size(); l++)

What is this l? Why declare it outside the loop? It seems you don't need it in the outer scope, so don't. And also the post-increment.

The result:

for(size_t l = 0; l < vector.size(); ++l)

I'm sorry for making code review out of this post.



This video can help you solving your question :)
By: admin