Click to jump to the REST-Framework column directory

Relational fields are used to represent data fields of model relationships. They can be applied to ForeignKey, ManyToManyField, and OneToOneField relationships, as well as to reverse relationships, custom relationships, etc., for example: GenericForeignKey.

Example model declaration:

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)
    order = models.IntegerField()
    title = models.CharField(max_length=100)
    duration = models.IntegerField()

    class Meta:
        unique_together = ['album'.'order']
        ordering = ['order']

    def __str__(self) :
        return '%d: %s' % (self.order, self.title)
Copy the code

StringRelatedField

This field enables a relational mapping of the target model class’s __str__ methods, such as the serializer in the example:

class AlbumSerializer(serializers.ModelSerializer) :
    tracks = serializers.StringRelatedField(many=True)

    class Meta:
        model = Album
        fields = ['album_name'.'artist'.'tracks']
Copy the code

The serialized data is represented as:

{
    'album_name': 'Things We Lost In The Fire'.'artist': 'Low'.'tracks': [
        '1: Sunflower'.'2: Whitetail'.'3: Dinosaur Act'. ] }Copy the code

parameter

  • many: If applied to many-to-many relationships, this parameter should be set toTrue

PrimaryKeyRelatedField

This field gradually represents the relational target, such as the serializer in the example:

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

    class Meta:
        model = Album
        fields = ['album_name'.'artist'.'tracks']
Copy the code

The serialized data is represented as:

{
    'album_name': 'Undun'.'artist': 'The Roots'.'tracks': [
        89.90.91. ] }Copy the code

parameter

  • queryset: Set of queries used for model instance lookups when validating field input. The relationship must be explicitly setquerysetread_only=True
  • many: If applied to many-to-many relationships, this parameter should be set toTrue
  • allow_null: If this parameter is set toTrue, the field will be acceptedNoneNullable relationship value or empty string. Default isFalse
  • pk_field: sets to a field to control the serialization/deserialization of primary key values, for examplepk_field=UUIDField(format='hex')Serialize the UUID primary key into its compact hexadecimal representation

HyperlinkedRelatedField

This field is used to represent the relational target using hyperlinks, such as the serializer in the example:

class AlbumSerializer(serializers.ModelSerializer) :
    tracks = serializers.HyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='track-detail'
    )

    class Meta:
        model = Album
        fields = ['album_name'.'artist'.'tracks']
Copy the code

The serialized data is represented as:

{
    'album_name': 'Graceland'.'artist': 'Paul Simon'.'tracks': [
        'http://www.example.com/api/tracks/45/'.'http://www.example.com/api/tracks/46/'.'http://www.example.com/api/tracks/47/'. ] }Copy the code

parameter

  • view_name: the view name that should be used as the target of the relationship. If you are using a standard router class, the string will be<modelname>-detail
  • queryset: Set of queries used for model instance lookups when validating field input. The relationship must be explicitly setquerysetread_only=True
  • many: If applied to many-to-many relationships, this parameter should be set toTrue
  • allow_null: If this parameter is set toTrue, the field will be acceptedNoneThe value or empty string of nullable relationships
  • lookup_field: The field applied to the lookup on the target, which should be the URL keyword parameter on the reference view. The default value is'pk'.
  • lookup_url_kwarg: Specifies the name of the keyword parameter defined in the URL conf. This parameter corresponds to the search field and the default value is the samelookup_field
  • format: If formatting suffixes are used, the hyperlink field will use the same formatting suffixes for the target unless usingformatParameter to override it

SlugRelatedField

This field uses the fields on the target to indicate the relational target, for example, serializer:

class AlbumSerializer(serializers.ModelSerializer) :
    tracks = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='title'
     )

    class Meta:
        model = Album
        fields = ['album_name'.'artist'.'tracks']
Copy the code

The serialized data is represented as:

{
    'album_name': 'Dear John'.'artist': 'Loney Dear'.'tracks': [
        'Airport Surroundings'.'Everything Turns to You'.'I Was Only Going Out'. ] }Copy the code

parameter

  • queryset: Set of queries used for model instance lookups when validating field input. The relationship must be explicitly setquerysetread_only=True
  • many: If applied to many-to-many relationships, this parameter should be set toTrue
  • allow_null: If this parameter is set toTrue, the field will be acceptedNoneThe value or empty string of nullable relationships

HyperlinkedIdentityField

This field can be used as an identification relationship application, such as the “URL” field on HyperlinkedIdentityField, or it can be used for object attributes, such as the serializer in the example:

class AlbumSerializer(serializers.HyperlinkedModelSerializer) :
    track_listing = serializers.HyperlinkedIdentityField(view_name='track-list')

    class Meta:
        model = Album
        fields = ['album_name'.'artist'.'track_listing']
Copy the code

The serialized data is represented as:

{
    'album_name': 'The Eraser'.'artist': 'Thom Yorke'.'track_listing': 'http://www.example.com/api/track_list/12/',}Copy the code

parameter

  • view_name: the view name that should be used as the target of the relationship. If you are using a standard router class, the string will be<modelname>-detail
  • lookup_field: The field applied to the lookup on the target, which should be the URL keyword parameter on the reference view. The default value is'pk'.
  • lookup_url_kwarg: Specifies the name of the keyword parameter defined in the URL conf. This parameter corresponds to the search field and the default value is the samelookup_field
  • format: If formatting suffixes are used, the hyperlink field will use the same formatting suffixes for the target unless usingformatParameter to override it

Nested relationships

Sample serializer:

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']
Copy the code

The serialized data is represented as:

>>> album = Album.objects.create(album_name="The Grey Album", artist='Danger Mouse')
>>> Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245)
<Track: Track object>
>>> Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264)
<Track: Track object>
>>> Track.objects.create(album=album, order=3, title='Encore', duration=159)
<Track: Track object>
>>> serializer = AlbumSerializer(instance=album)
>>> serializer.data
{
    '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},... ] ,}Copy the code

Writable Nested Serializers

By default, nested Serializer is read-only, and if you want to support write operations to nested serializer fields, you need to create create() or update() methods to explicitly specify how child relationships should be saved. Such as:

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

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

    class Meta:
        model = Album
        fields = ['album_name'.'artist'.'tracks']

    def create(self, validated_data) :
        tracks_data = validated_data.pop('tracks')
        album = Album.objects.create(**validated_data)
        for track_data in tracks_data:
            Track.objects.create(album=album, **track_data)
        return album

>>> data = {
    '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},],}>>> serializer = AlbumSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.save()
<Album: Album object>
Copy the code