ModelSerializer vs HyperlinkedModelSerializer
- ModelSerializer
- By default, Relationship will show –>
as primary keys
- By default, Relationship will show –>
- HyperlinkedModelSerializer
- By default, Relationship will show –>
as url
- By default, Relationship will show –>
# This (ModelSerializer)
{
"id": 3,
"question": "What is MF",
"author": 2
},
# Turns to this (HyperlinkedModelSerializer)
{
"url": "http://127.0.0.1:8000/api/questions/3/",
"question": "What is MF",
"author": "http://127.0.0.1:8000/users/2/"
},
Doc: https://www.django-rest-framework.org/api-guide/relations/
Doc: https://www.django-rest-framework.org/api-guide/serializers/#hyperlinkedmodelserializer
View CODE here: https://github.com/amrit94/drf-test/blob/08-Relationship-and-Hyperlink/snippets/serializers.py
7.1 ReadOnlyField
- This will be readonly-field, can’t edit
- GET will display owner-field, But POST will not accept owner-field
# serializer.py
owner = serializers.ReadOnlyField(source='owner.username')
# If above line not used --> primary-key will be displayed
{"owner": 1} --> { "owner": "dev"}
The source argument controls which attribute is used to populate a field, and can point at any attribute on the serialized instance.
It can also take the dotted notation shown above, in which case it will traverse the given attributes, in a similar way as it is used with Django’s template language
7.2 PrimaryKeyRelatedField
- Used in
reverse relationship
- related_name in Model in needed
Because ‘snippets’ is a reverse relationship
on the User model,
it will not be included by default when using the ModelSerializer class, so we needed to add an explicit field
for it.
- Related field
primary-key is displayed
# serializer.py
snippet_owner = serializers.PrimaryKeyRelatedField(many=True,
queryset=Snippet.objects.all())
# OR
snippet_owner = serializers.PrimaryKeyRelatedField(many=True,
read_only=True)
- NOTE:
snippet_owner --> related_name
# API - OUTPUT
[{
"id": 1,
"username": "localadmin",
"snippet_owner": [
2,
3
]
},]
Arguments:
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
.
many - If applied to a to-many relationship, you should set this argument to True.
allow_null - If set to True, the field will accept values of None or the empty string for nullable relationships. Defaults to False.
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.
7.3 StringRelatedField
- Used in
reverse relationship
- related_name in Model in needed
- Displays data
returned by __str__()
in models – instead of primary-key - NOTE
- Model ‘related-name’ is mandatory
snippet_owner = serializers.StringRelatedField(many=True)
# person = serializers.StringRelatedField() # O2O
# person_post = serializers.StringRelatedField(many=True) # M2O
# publications = serializers.StringRelatedField(many=True) # M2M
# http://127.0.0.1:8000/users/
[{
"id": 1,
"username": "localadmin",
"snippet_owner": [
"2: L2",
"3: L2"
]
},]
Arguments
many - If applied to a to-many relationship, you should set this argument to True.
7.4 SlugRelatedField
- Used in
reverse relationship
- related_name in Model in needed
- Can display any field of the related model
snippet_owner = serializers.SlugRelatedField(many=True,
read_only=True, slug_field='language')
[{
"id": 1,
"username": "localadmin",
"snippet_owner": [
"js",
"java"
]
},]
Arguments
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. 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.
many - If applied to a to-many relationship, you should set this argument to True.
allow_null - If set to True, the field will accept values of None or the empty string for nullable relationships. Defaults to False.
7.5 HyperlinkedRelatedField
- Used in
reverse relationship
- related_name in Model in needed
HyperlinkedRelatedField may be used to represent the target of the relationship using a hyperlink.
snippet_owner = serializers.HyperlinkedRelatedField(many=True,
view_name='snippet-detail', read_only=True)
[{
"id": 1,
"username": "localadmin",
"snippet_owner": [
"http://127.0.0.1:8000/snippets/2/",
"http://127.0.0.1:8000/snippets/3/"
]
},]
Arguments:
view_name - The view_name is the name of url-pattern.
If you’re using the standard router classes 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.
many - If applied to a to-many relationship, you should set this argument to True.
allow_null - If set to True, the field will accept values of None or the empty string for nullable relationships. Defaults to False.
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.
7.6 HyperlinkedIdentityField
- Used in HyperlinkedModelSerializer
- many=True is removed
- Only first value will be shown
snippet_owner = serializers.HyperlinkedIdentityField(
view_name='snippet-detail', read_only=True)
[{
"id": 1,
"username": "localadmin",
"snippet_owner": "http://127.0.0.1:8000/snippets/1/"
},]
Arguments
view_name - The view name that should be used as the target of the relationship. If you’re using the standard router classes 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.
7.7 Display related model
- M2O, M2M
- If rel_name not defined –> source required
- source=
<model_name>_set
is used
- source=
- If rel_name not defined –> source required
class PersonSerializer(serializers.ModelSerializer):
# If rel_name not defined
person_post = PostsSerializer(source='posts_set', many=True)
# If rel_name is defined
# person_post = PostsSerializer(many=True)