Using SlugRelatedField in Django REST Framework

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

Tags:- Python Django DRF

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 or email) 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.