Django REST Framework:depth=1时限制外键关联字段及用户字段
Hey there, let's break down how to solve your two Django REST Framework issues step by step!
depth=1 The problem with depth=1 is that it automatically expands all fields from the related model, leaving you no control over which ones are included. Instead of relying on depth, the better approach is to use nested serializers to explicitly define exactly which related fields you want to expose.
Let's use an example: suppose you have a Post model that links to a User via a foreign key. Instead of using depth=1 to expand the user data, you can create a minimal nested serializer for the user, then reference it in your main serializer.
# models.py from django.db import models from django.contrib.auth.models import User class Post(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(User, on_delete=models.CASCADE)
# serializers.py from rest_framework import serializers from .models import Post from django.contrib.auth.models import User # First, create a slimmed-down serializer for the related User model class MinimalUserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'username') # Only include the fields you need # Now use this nested serializer in your Post serializer instead of depth class PostSerializer(serializers.ModelSerializer): author = MinimalUserSerializer() # Replaces depth=1 with controlled fields class Meta: model = Post fields = ('id', 'title', 'author')
This way, you get the expanded relationship without all the extra, unwanted fields. There's no direct way to restrict fields when using depth=1, so nested serializers are the DRF-recommended solution here.
UserSerializer to Restrict User Data Since you already have a UserSerializer that only includes the fields you need, implementing this depends on how you're using serializers in your views:
Scenario 1: Custom Views
If you're building your own API views (like APIView or GenericAPIView subclasses), simply specify your custom serializer in the view:
# views.py from rest_framework import generics from django.contrib.auth.models import User from .serializers import UserSerializer # Import your custom serializer class UserListAPIView(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserSerializer # Use your custom serializer here
Scenario 2: ModelViewSets
If you're using DRF's ModelViewSet for user endpoints, override the serializer_class attribute in your viewset:
# views.py from rest_framework import viewsets from django.contrib.auth.models import User from .serializers import UserSerializer class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer # Replace the default serializer
Bonus: Global Replacement (Optional)
If you want to use your custom serializer across all default DRF user-related views, you can add a setting in settings.py:
# settings.py REST_FRAMEWORK = { 'DEFAULT_SERIALIZER_CLASSES': { 'rest_framework.serializers.ModelSerializer': 'your_app.serializers.UserSerializer', } }
That said, it's usually better to specify the serializer per-view to avoid unintended side effects elsewhere in your project.
Just double-check that your UserSerializer excludes sensitive fields like the hashed password:
# serializers.py from rest_framework import serializers from django.contrib.auth.models import User class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'username', 'email') # Include only what you need # Alternatively, exclude unwanted fields: # exclude = ('password', 'is_superuser', 'is_staff')
This ensures no sensitive user data (like hashed passwords) gets returned in your API responses.
内容的提问来源于stack exchange,提问作者HenryM

