Using PrimaryKeyRelatedField in Django REST Framework
Last updated 1 month, 1 week ago | 156 views 75 5

When working with relational data in Django REST Framework, you often need to represent relationships like ForeignKey
, OneToOneField
, or ManyToManyField
. While nested serializers are great for displaying related data, sometimes all you need is to represent the relationship using just the primary key.
That’s where PrimaryKeyRelatedField
comes in.
What is PrimaryKeyRelatedField
?
PrimaryKeyRelatedField
is a serializer field in DRF that represents relationships using primary keys (typically integer IDs). It’s useful when you want to reference related objects by ID only, without serializing the full object.
✅ When to Use It
-
When you only need the ID of the related object
-
When you’re creating/updating objects via API and want to pass related IDs
-
When you want to keep the payload simple and efficient
Basic Syntax
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
author = serializers.PrimaryKeyRelatedField(queryset=Author.objects.all())
class Meta:
model = Book
fields = ['title', 'author']
This tells DRF: "The author
field will be represented by its primary key (e.g., author_id
)".
Example: Book and Author
Models
# models.py
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
Serializer
# serializers.py
class BookSerializer(serializers.ModelSerializer):
author = serializers.PrimaryKeyRelatedField(queryset=Author.objects.all())
class Meta:
model = Book
fields = ['id', 'title', 'author']
Request Payload
To create a book:
POST /api/books/
{
"title": "Django REST Mastery",
"author": 3
}
Here, 3
is the ID of the related Author
.
Reverse Relationships
For reverse relationships (e.g., all books by an author), you can use PrimaryKeyRelatedField(many=True)
.
class AuthorSerializer(serializers.ModelSerializer):
books = serializers.PrimaryKeyRelatedField(
many=True,
read_only=True
)
class Meta:
model = Author
fields = ['id', 'name', 'books']
Assuming the related name is books
, this will output:
{
"id": 1,
"name": "Jane Austen",
"books": [1, 3, 5]
}
✨ Read vs Write
Case | Use |
---|---|
Read-only | Use read_only=True |
Write-only | Provide queryset=... |
Read and Write | Combine both: PrimaryKeyRelatedField(queryset=...) |
Validation
DRF will validate the primary key against the provided queryset. If you pass an invalid ID, it will return a 400 Bad Request
error.
{
"author": ["Invalid pk \"9999\" - object does not exist."]
}
Advanced Usage
Optional ForeignKey
author = serializers.PrimaryKeyRelatedField(
queryset=Author.objects.all(),
required=False,
allow_null=True
)
Filtering by User
def get_queryset(self):
return Author.objects.filter(user=self.context['request'].user)
Then use:
author = serializers.PrimaryKeyRelatedField(queryset=get_queryset)
⚠️ Common Pitfalls
Pitfall | Solution |
---|---|
❌ Not providing a queryset |
Required for write operations |
❌ Wrong related name in reverse relationships | Check model's related_name |
❌ Trying to use without ID | This field only works with primary key references |
✅ Tips & Best Practices
Tip | Why |
---|---|
✅ Use for simple ID-based relationships | Keeps payloads small |
✅ Combine with SlugRelatedField if needed |
More readable than raw IDs |
✅ Use nested serializers if you need full object | Use case decides field type |
✅ Always test invalid IDs | Ensures validation works correctly |
Summary
Feature | Value |
---|---|
Field | PrimaryKeyRelatedField |
Use Case | Represent relationships by ID |
Best For | Simple read/write of related objects |
Alternate Options | SlugRelatedField , HyperlinkedRelatedField , nested serializers |
Full Example
class BookSerializer(serializers.ModelSerializer):
author = serializers.PrimaryKeyRelatedField(queryset=Author.objects.all())
class Meta:
model = Book
fields = ['id', 'title', 'author']
POST /api/books/
{
"title": "Learn Django",
"author": 2
}
Conclusion
PrimaryKeyRelatedField
is one of the most efficient and practical tools for handling relational fields in Django REST Framework. It allows your API to remain simple and lean, while still providing all the power of relational integrity.