> Good programmers worry about data structures and their relationships.
>
> — [Linus Torvalds][cite]
Relational fields are used to represent model relationships. They can be applied to `ForeignKey`, `ManyToManyField` and `OneToOneField` relationships, as well as to reverse relationships, and custom relationships such as `GenericForeignKey`.
**Note:** The relational fields are declared in `relations.py`, but by convention you should import them from the `serializers` module, using `from rest_framework import serializers` and refer to fields as `serializers.<FieldName>`.
When using the `ModelSerializer` class, serializer fields and relationships will be automatically generated for you. Inspecting these automatically generated fields can be a useful tool for determining how to customize the relationship style.
To do so, open the Django shell, using `python manage.py shell`, then import the serializer class, instantiate it, and print the object representation…
>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>>> print repr(serializer) # Or `print(repr(serializer))` in Python 3.x.
AccountSerializer():
id = IntegerField(label='ID', read_only=True)
name = CharField(allow_blank=True, max_length=100, required=False)
In order to explain the various types of relational fields, we'll use a couple of simple models for our examples. Our models will be for music albums, and the tracks listed on each album.
*`queryset` - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set `read_only=True`.
*`pk_field` - Set to a field to control serialization/deserialization of the primary key's value. For example, `pk_field=UUIDField(format='hex')` would serialize a UUID primary key into its compact hex representation.
*`view_name` - The view name that should be used as the target of the relationship. If you're using [the standard router classes][routers] this will be a string with the format `<modelname>-detail`. **required**.
*`queryset` - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set `read_only=True`.
*`lookup_field` - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is `'pk'`.
*`lookup_url_kwarg` - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as `lookup_field`.
*`format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
## SlugRelatedField
`SlugRelatedField` may be used to represent the target of the relationship using a field on the target.
By default this field is read-write, although you can change this behavior using the `read_only` flag.
When using `SlugRelatedField` as a read-write field, you will normally want to ensure that the slug field corresponds to a model field with `unique=True`.
*`slug_field` - The field on the target that should be used to represent it. This should be a field that uniquely identifies any given instance. For example, `username`. **required**
*`queryset` - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set `read_only=True`.
This field can be applied as an identity relationship, such as the `'url'` field on a HyperlinkedModelSerializer. It can also be used for an attribute on the object. For example, the following serializer:
class AlbumSerializer(serializers.HyperlinkedModelSerializer):
*`view_name` - The view name that should be used as the target of the relationship. If you're using [the standard router classes][routers] this will be a string with the format `<model_name>-detail`. **required**.
*`lookup_field` - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is `'pk'`.
*`lookup_url_kwarg` - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as `lookup_field`.
*`format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
To implement a custom relational field, you should override `RelatedField`, and implement the `.to_representation(self, value)` method. This method takes the target of the field as the `value` argument, and should return the representation that should be used to serialize the target. The `value` argument will typically be a model instance.
The `queryset` argument is only ever required for *writable* relationship field, in which case it is used for performing the model instance lookup, that maps from the primitive user input, into a model instance.
In version 2.x a serializer class could *sometimes* automatically determine the `queryset` argument *if* a `ModelSerializer` class was being used.
This behavior is now replaced with *always* using an explicit `queryset` argument for writable relational fields.
Doing so reduces the amount of hidden 'magic' that `ModelSerializer` provides, makes the behavior of the field more clear, and ensures that it is trivial to move between using the `ModelSerializer` shortcut, or using fully explicit `Serializer` classes.
Note that reverse relationships are not automatically included by the `ModelSerializer` and `HyperlinkedModelSerializer` classes. To include a reverse relationship, you must explicitly add it to the fields list. For example:
You'll normally want to ensure that you've set an appropriate `related_name` argument on the relationship, that you can use as the field name. For example:
If you have not set a related name for the reverse relationship, you'll need to use the automatically generated related name in the `fields` argument. For example:
See the Django documentation on [reverse relationships][reverse-relationships] for more details.
## Generic relationships
If you want to serialize a generic foreign key, you need to define a custom field, to determine explicitly how you want serialize the targets of the relationship.
For example, given the following model for a tag, which has a generic relationship with other arbitrary models:
class TaggedItem(models.Model):
"""
Tags arbitrary model instances using a generic relation.
And the following two models, which may be have associated tags:
class Bookmark(models.Model):
"""
A bookmark consists of a URL, and 0 or more descriptive tags.
"""
url = models.URLField()
tags = GenericRelation(TaggedItem)
class Note(models.Model):
"""
A note consists of some text, and 0 or more descriptive tags.
"""
text = models.CharField(max_length=1000)
tags = GenericRelation(TaggedItem)
We could define a custom field that could be used to serialize tagged instances, using the type of each instance to determine how it should be serialized.
class TaggedObjectRelatedField(serializers.RelatedField):
"""
A custom field to use for the `tagged_object` generic relationship.
If you need the target of the relationship to have a nested representation, you can use the required serializers inside the `.to_representation()` method:
raise Exception('Unexpected type of tagged object')
return serializer.data
Note that reverse generic keys, expressed using the `GenericRelation` field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known.
For more information see [the Django documentation on generic relations][generic-relations].