Using PrimaryKeyRelatedField in Django REST Framework

Last updated 1 month, 1 week ago | 156 views 75     5

Tags:- Python Django DRF

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.