Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-rest-framework: Setting up serializer for foreign key

In my model, I have two tables named: Vtable and Vdata. Each virtual table (in Vtable) has entries of virtual data stored in Vdata.

I'm trying to make a view that would show the list of Vdata corresponding to each Vtable

My serializer isn't working and I think it's because I'm doing it backwards. I think the problem is in this line: table_id = serializers.RelatedField(many=True)

For reference, I get this error: 'Vtable' object is not iterable

Here is my models.py:

from django.db import models
from django.contrib.auth.models import User

class Vtable(models.Model):
    user = models.ForeignKey(User)
    table_name = models.CharField(max_length=200)
    added_date = models.DateTimeField('date added')
    def __unicode__(self):
        return self.table_name

class Vdata(models.Model):
    table_id = models.ForeignKey(Vtable)
    table_pk = models.IntegerField()
    column_1 = models.CharField(max_length=200)
    column_2 = models.CharField(max_length=200)
    added_date = models.DateTimeField('date added')
    def __unicode__(self):
        return str(self.added_date)

Here is my serializers.py:

from django.contrib.auth.models import User, Group
from rest_framework import serializers
from vtables.models import Vtable, Vdata

class TableSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.Field(source='user.username')

    class Meta:
        model = Vtable
        fields = ('table_name', 'added_date', 'user')

class EntrySerializer(serializers.HyperlinkedModelSerializer):
    table_id = serializers.RelatedField(many=True)

    class Meta:
        model = Vdata
        fields = ('table_id', 'table_pk', 'column_1', 'column_2', 'added_date')

Here is the view that calls it:

class EntryList(APIView):
    def get(self, request, format=None):
        entries = Vdata.objects.all()
        serializer = EntrySerializer(entries, many=True)
        return Response(serializer.data

        class Meta:
            model = Vdata
            fields = ('table_id', 'table_pk', 'column_1', 'column_2', 'added_date')
like image 244
adrianmc Avatar asked Aug 08 '14 11:08

adrianmc


People also ask

How do you save a foreign key field in Django REST framework?

Your code is using serializer only for validation, but it is possible use it to insert or update new objects on database calling serializer. save() . To save foreign keys using django-rest-framework you must put a related field on serializer to deal with it. Use PrimaryKeyRelatedField .

How do I change the foreign key in Django REST framework?

As stated in the documentation, you will need to write your own create() and update() methods in your serializer to support writable nested data. You will also need to explicitly add the status field instead of using the depth argument otherwise I believe it won't be automatically added to validated_data .

How does django store foreign key values?

Note that the _id in the artist parameter, Django stores foreign keys id in a field formed by field_name plus _id so you can pass the foreign key id directly to that field without having to go to the database again to get the artist object.

Why serializers are used in django?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.


1 Answers

Here is an example of how you might do this:

class TableSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.Field(source='user.username')
    entries = EntrySerializer(many=True)

    class Meta:
        model = Vtable
        fields = ('table_name', 'added_date', 'user', 'entries')

class EntrySerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Vdata
        fields = ('table_id', 'table_pk', 'column_1', 'column_2', 'added_date')

And for the view:

class EntryList(GenericAPIView):
    queryset = Vtable.objects.all()
    serializer_class = TableSerializer

Do not forget about:

setting related_name='entries' in your model foreign key field definition.

like image 98
AdelaN Avatar answered Oct 18 '22 08:10

AdelaN