In Django REST Framework (DRF), relationships between models are often represented by their primary keys. However, in many APIs, using human-readable identifiers (like a username, email, or a slug field) is more user-friendly and expressive.
That’s where SlugRelatedField
comes in.
What is SlugRelatedField
?
SlugRelatedField
lets you represent relationships using a field (slug) of the related object, instead of its primary key. This is helpful when you want to use a readable string such as username
, email
, or slug
instead of an ID.
✅ When to Use SlugRelatedField
-
You want to use custom identifiers (e.g.,
username
oremail
) for related objects -
You prefer more readable and meaningful API payloads
-
You need to filter or access objects by a unique field other than the primary key
Syntax
SlugRelatedField(
slug_field='field_name',
queryset=RelatedModel.objects.all()
)
-
slug_field
: The field on the related model to use (e.g.,'username'
) -
queryset
: The list of valid objects for this relation (used for validation)
Example: Book and Author
Models
# models.py
class Author(models.Model):
name = models.CharField(max_length=100)
username = models.SlugField(unique=True)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
Serializer with SlugRelatedField
# serializers.py
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
author = serializers.SlugRelatedField(
queryset=Author.objects.all(),
slug_field='username'
)
class Meta:
model = Book
fields = ['id', 'title', 'author']
Request Example
POST /api/books/
{
"title": "Django for APIs",
"author": "johndoe"
}
In this case, "johndoe"
is the username
of the author.
Response Example
{
"id": 1,
"title": "Django for APIs",
"author": "johndoe"
}
Reverse Relationships
You can also use SlugRelatedField
in reverse relations (e.g., a list of books for an author).
class AuthorSerializer(serializers.ModelSerializer):
books = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field='title'
)
class Meta:
model = Author
fields = ['id', 'username', 'books']
Response:
{
"id": 1,
"username": "johndoe",
"books": ["Book A", "Book B"]
}
Read-Only vs Read/Write
Use Case | Code |
---|---|
Read-only | SlugRelatedField(slug_field='title', read_only=True) |
Write-only | SlugRelatedField(slug_field='title', queryset=...) |
Read & Write | Both slug_field and queryset provided |
⚠️ Validation
DRF will validate that the submitted slug exists in the provided queryset. If not:
{
"author": ["Object with username=johndoe123 does not exist."]
}
✅ Best Practices
Tip | Why |
---|---|
✅ Use unique slug fields | Prevents conflicts and ambiguity |
✅ Stick to short, readable slugs | Improves user experience |
✅ Avoid sensitive slugs (like email ) unless required |
Protects privacy |
✅ Always validate uniqueness in your model | Add unique=True on the slug field |
Comparison Table
Field Type | Represents | Use Case |
---|---|---|
PrimaryKeyRelatedField |
ID (e.g., 3 ) |
Internal logic, performance |
SlugRelatedField |
Readable string (e.g., johndoe ) |
Clean, user-facing APIs |
HyperlinkedRelatedField |
URL to object | RESTful, navigable APIs |
Nested serializer | Full object | Rich detail, customization |
Full Working Example
models.py
class Author(models.Model):
username = models.SlugField(unique=True)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
serializers.py
class BookSerializer(serializers.ModelSerializer):
author = serializers.SlugRelatedField(
queryset=Author.objects.all(),
slug_field='username'
)
class Meta:
model = Book
fields = ['id', 'title', 'author']
Sample Request
POST /api/books/
{
"title": "Advanced Django",
"author": "janedoe"
}
Common Pitfalls
Problem | Fix |
---|---|
❌ Non-unique slug field | Set unique=True on model field |
❌ Invalid slug during POST | Ensure value exists in queryset |
❌ Not passing queryset | Required for write operations |
❌ Using complex fields as slug | Stick to simple string fields |
✅ Summary
Concept | Description |
---|---|
SlugRelatedField |
Represents related objects using a custom field like username or slug |
slug_field |
Field on the related model used for lookups |
queryset |
List of valid related objects |
Best for | Clean, user-readable APIs |
Conclusion
SlugRelatedField
is a clean and efficient way to represent related models using human-readable values. It improves your API’s usability and makes request/response payloads more meaningful to users.
Use it when you want to avoid exposing internal IDs and prefer user-facing identifiers.