You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django集成Auth0认证后,viewable字段JSON返回空列表的解决问询

问题描述

在Django应用中使用Auth0实现认证功能,新用户可正常在Admin面板创建,整体功能运行良好,但访问数据展示接口时,返回的JSON中viewable字段始终为空列表,示例如下:

{
    "id": "d458196e-49f1-42db-8bc2-ee1dba438953",
    "owner": 1,
    "name": "dsdsds",
    "viewable": []
}

viewable字段用于存储可查看该数据对象的用户列表,可通过添加用户邮箱实现数据共享。该字段在Django Admin和DRF表单中均可正常查看,但无法在JSON接口中展示数据。

相关代码

Models.py

from django.contrib.auth.models import AbstractUser
from django.conf import settings
import uuid

class User(AbstractUser):
    pass

class WalletInstance(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
    name = models.CharField(max_length=30, null=True)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='owner', on_delete=models.CASCADE)
    viewable = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='can_view', blank=True)

Settings.py

AUTH_USER_MODEL = 'budget_app.User'

SOCIAL_AUTH_TRAILING_SLASH = False
SOCIAL_AUTH_AUTH0_DOMAIN = '####'
SOCIAL_AUTH_AUTH0_KEY = '####'
SOCIAL_AUTH_AUTH0_SECRET = '####'
SOCIAL_AUTH_AUTH0_SCOPE = [
    'openid',
    'profile',
    'email'
]

AUTHENTICATION_BACKENDS = {
    'social_core.backends.auth0.Auth0OAuth2',
    'django.contrib.auth.backends.ModelBackend'
}

LOGIN_URL = '/login/auth0'
LOGIN_REDIRECT_URL = '/'
LOGOUT_REDIRECT_URL = '/'

Serializers.py

from rest_framework import serializers
from .models import WalletInstance

class WalletInstanceSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.id')
    class Meta:
        model = WalletInstance
        fields = '__all__'
        depth = 1
解决方法

问题核心是DRF序列化器未正确处理多对多关联字段的序列化,可通过以下方式修复:

方式一:显式指定多对多字段的序列化器

自定义User序列化器,明确viewable字段的序列化规则:

from rest_framework import serializers
from .models import User, WalletInstance

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'username', 'email') # 按需选择要展示的用户字段

class WalletInstanceSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.id')
    viewable = UserSerializer(many=True, read_only=True) # 为多对多字段指定序列化器
    class Meta:
        model = WalletInstance
        fields = '__all__'
        # 移除depth=1,避免与显式序列化规则冲突

方式二:调整depth参数并优化关联数据加载

若不想自定义User序列化器,可移除owner的自定义字段,让depth=1自动展开所有关联关系:

class WalletInstanceSerializer(serializers.ModelSerializer):
    class Meta:
        model = WalletInstance
        fields = '__all__'
        depth = 1

注:此方式会让owner字段返回完整用户对象而非仅ID,若需保留owner为ID格式,优先选择方式一。

额外优化:确保关联数据被预加载

在视图层使用prefetch_related优化查询,确保多对多关联数据被正确加载:

from rest_framework import viewsets
from .models import WalletInstance
from .serializers import WalletInstanceSerializer

class WalletInstanceViewSet(viewsets.ModelViewSet):
    queryset = WalletInstance.objects.all().prefetch_related('viewable')
    serializer_class = WalletInstanceSerializer

内容的提问来源于stack exchange,提问作者rafaelHTML

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:36:21