Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django REST-framework: Using serializer for simple ForeignKey-relationship

I'm using the django REST-framework and try to map a simple foreign-key relationship to provide related data for further use, similar to the following request:

Using reverse relationships with django-rest-framework's serializer

Instead of a result, I receive the following exception:

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

Models:

    class Album(models.Model):
        album_name = models.CharField(max_length=100)
        artist = models.CharField(max_length=100)

    class Track(models.Model):
        # album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
        album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)
        order = models.IntegerField()
        title = models.CharField(max_length=100)
        duration = models.IntegerField()

        class Meta:
            unique_together = ('album', 'order')
            ordering = ['order']

        def __unicode__(self):
            return '%d: %s' % (self.order, self.title)

Serializers:

class AlbumSerializer(serializers.ModelSerializer):
    class Meta:
        model = Album
        fields = ('id', 'album_name', 'artist' )
class TrackSerializer(serializers.ModelSerializer):
    album_id = AlbumSerializer(many=False, read_only=True)
    class Meta:
        model = Track
        fields = ('order', 'title', 'duration', 'album_id')

View:

class TrackView(viewsets.ModelViewSet):
    queryset = Track.objects.all().select_related('album')
    serializer_class = serializers.TrackSerializer

What I have tried so far:

  1. Serializing Albums with related tracks as nested serializers, using a reverse relationship => works
  2. Doing the work just for the TrackSerializer without nested Album => works
  3. Doing the work just for the AlbumSerializer => works
  4. Using the TrackSerializer as shown in the code-section but reducing the AlbumSerializer by every field except for the primary key 'id' => works (but I would need the whole data set of album)
  5. Changed the nested Serializer to a many-relationship by setting many=True. => dumps, since the framework tries to iterate on all fields of AlbumSerializer.

Since I'm running out of ideas and material to browse for I'm asking the question: How to list all or single attributes (!= PrimaryKey) of Album for each Track in regards to my example.

like image 410
moleson Avatar asked Feb 25 '18 16:02

moleson


People also ask

What are serializer relations in Django REST framework?

In Django REST Framework, we have different types of serializers to serialize object instances, and the serializers have different serializer relations to represent model relationships. In this section, we will discuss the different serializer relations provided by Django REST Framework Serializers.

What is a serializer in REST framework?

Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data. The serializers in REST framework work very similarly to Django’s Form and ModelForm classes. The two major serializers that are most popularly used are ModelSerializer and HyperLinkedModelSerialzer.

What is the difference between Django and Django REST framework?

With Django the validation is performed partially on the form, and partially on the model instance. With Django Rest Framework the validation is performed entirely on the serializer class. When you’re using ModelSerializer all of this is handled automatically for you.

How to create a relational field in Django?

To do so, open the Django shell, using python manage.py shell, then import the serializer class, instantiate it, and print the object representation… In order to explain the various types of relational fields, we'll use a couple of simple models for our examples.


1 Answers

album_id in Track model is just album's primary key, so you have int type in error description. You need to specify whole album object by using album field instead of album_id:

class TrackSerializer(serializers.ModelSerializer):
    album = AlbumSerializer(many=False, read_only=True)
    class Meta:
        model = Track
        fields = ('order', 'title', 'duration', 'album')
like image 94
neverwalkaloner Avatar answered Sep 28 '22 15:09

neverwalkaloner