Django Rest Framework视图集正在返回选定的记录,而不是列表视图中的所有记录

Django Rest Framework视图集正在返回选定的记录,而不是列表视图中的所有记录,django,django-rest-framework,Django,Django Rest Framework,我有一个django应用程序。我的应用程序中有一部分无法正常工作。到目前为止,我正在使用django rest框架视图集。我想要的是两个基本上在同一个视图集中有两个不同的列表视图。1返回accountviewset中的所有帐户,另一个列表视图根据帐户模型中的用户foreignkey返回与用户关联的所有帐户 下面的代码返回与特定人员关联的所有帐户,但我无法使用列表视图返回数据库中的所有帐户 class AccountViewSet(viewsets.ModelViewSet): seria

我有一个django应用程序。我的应用程序中有一部分无法正常工作。到目前为止,我正在使用django rest框架视图集。我想要的是两个基本上在同一个视图集中有两个不同的列表视图。1返回accountviewset中的所有帐户,另一个列表视图根据帐户模型中的用户foreignkey返回与用户关联的所有帐户

下面的代码返回与特定人员关联的所有帐户,但我无法使用列表视图返回数据库中的所有帐户

class AccountViewSet(viewsets.ModelViewSet):
    serializer_class = AccountSerializer
    queryset = Account.objects.all()
    lookup_field = 'user__username'

    def list(self, request):
        queryset = Account.objects.all()
        serializer_class = AccountSerializer

        def get_object(self):
            return self.queryset.get(user__username=self.kwargs.get('username'))
**更新**

class AccountViewSet(viewsets.ModelViewSet):
    queryset = Account.objects.all();
    serializer_class = AccountSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_fields = ('user', 'name', '_class')
    lookup_field = 'user__username'

    # def get_queryset(self):
    #     return self.queryset.filter(user__username=self.kwargs.get('username'))
当有一个帐户与一个用户关联时,它工作。 无法处理2个以上的帐户,错误为:

MultipleObjectsReturned at /api/users/accounts/omarjandali/
get() returned more than one Account -- it returned 2!
其他尝试不会返回端点中有特定用户或没有用户的任何帐户

最大的问题是,它返回的是用户id,而不是用户用户名

当前代码:

serializers.py:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'is_staff')

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = ('user', 'gender', 'phone', 'ip_address', 'dob_month', 'dob_day',
                  'dob_year', 'address_street', 'address_city', 'address_state',
                  'address_postal', 'address_country', 'profile_pic', 'role')

class FriendSerializer(serializers.ModelSerializer):
    class Meta:
        model = Friend
        fields = ('requested', 'friended', 'status', 'blocked')

class AccountSerializer(serializers.ModelSerializer):
    user = UserSerializer(
        read_only = True,
    )

    class Meta:
        model = Account
        fields = ('user', '_id', 'name', 'balance', 'currency', 'bank_name',
                  'routing', '_class', 'type', 'active', 'main', 'synapse')
Views.py:

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.all()
    lookup_field = 'username'

class ProfileViewSet(viewsets.ModelViewSet):
    serializer_class = ProfileSerializer
    queryset = Profile.objects.all()
    lookup_field = 'user__username'

class FriendViewSet(viewsets.ModelViewSet):
    serializer_class = FriendSerializer
    querset = Friend.objects.all()
    lookup_field = 'user__username'

class AccountViewSet(viewsets.ModelViewSet):
    queryset = Account.objects.all();
    serializer_class = AccountSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('user',)
网址:

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'profiles', ProfileViewSet, basename='profile')
router.register(r'friends', FriendViewSet, basename='friend')
router.register(r'accounts', AccountViewSet, basename='account')
urlpatterns = router.urls

首先,您的代码有很多问题。如果需要返回列表,则应在
get\u object
方法中进行筛选。它意味着只返回一个实例,因此在
get\u queryset
方法中可以这样做。其次,list方法中的
get\u object()
是错误的。第三,在list方法中分配序列化器类没有意义。它甚至在调用该方法之前就被赋值了

现在回到您的问题,“列表”是一个视图集操作,您不能执行两次。相反,您可以在列表端点上添加。 为此,只需在viewset的action方法中添加一个方法

在您的特定情况下,我将这样做:我将引入一个实例变量,
qs\u type
,用于控制
get\u queryset()方法返回的结果类型

大概是这样的:

def __init__(self, *args, **kwargs):
    self.qs_type = 'user_only'
    super().__init__(*args, **kwargs)

def get_queryset(self):
    if self.qs_type == 'user_only':
        qs = Account.objects.filter(username=self.kwargs.get('username'))
    else:
        qs = Account.objects.all()
    return qs)


@action(detail=False, methods=['get'])
def all(self, request, *args, **kwargs):
    self.qs_type = 'all'
    return self.list(request, *args, **kwargs)

这假定在默认情况下,将返回用户名筛选版本,而在新操作中将返回所有帐户。如果您确定不需要更多类似的操作,您可以将
qs_type
设置为布尔值,但为了以防万一,我将其设置为字符串。我不知道你的url是如何配置的,所以我真的不知道如何从url kwargs中检索用户名,但是这段代码应该可以帮助你解决问题。首先,你的代码有很多问题。如果需要返回列表,则应在
get\u object
方法中进行筛选。它意味着只返回一个实例,因此在
get\u queryset
方法中可以这样做。其次,list方法中的
get\u object()
是错误的。第三,在list方法中分配序列化器类没有意义。它甚至在调用该方法之前就被赋值了

现在回到您的问题,“列表”是一个视图集操作,您不能执行两次。相反,您可以在列表端点上添加。 为此,只需在viewset的action方法中添加一个方法

在您的特定情况下,我将这样做:我将引入一个实例变量,
qs\u type
,用于控制
get\u queryset()方法返回的结果类型

大概是这样的:

def __init__(self, *args, **kwargs):
    self.qs_type = 'user_only'
    super().__init__(*args, **kwargs)

def get_queryset(self):
    if self.qs_type == 'user_only':
        qs = Account.objects.filter(username=self.kwargs.get('username'))
    else:
        qs = Account.objects.all()
    return qs)


@action(detail=False, methods=['get'])
def all(self, request, *args, **kwargs):
    self.qs_type = 'all'
    return self.list(request, *args, **kwargs)

这假定在默认情况下,将返回用户名筛选版本,而在新操作中将返回所有帐户。如果您确定不需要更多类似的操作,您可以将
qs_type
设置为布尔值,但为了以防万一,我将其设置为字符串。我不知道您的url是如何配置的,所以我真的不知道如何从url kwargs检索用户名,但这段代码应该可以帮助您解决问题

Ok。非常感谢。问题。。。因此,如果我按照上面的方法进行操作,我将初始化vewset,然后创建列表视图的两个操作。它将检查是否有传递到url末尾的参数。如果是,则筛选;如果是,则显示全部。基本上这就是正确的方向?
@action
对列表视图有什么影响?我的另一个问题是。。。因此,我创建了视图集并添加了
序列化器_类
查询集
,但在
定义列表
中,我将创建双重操作???如果我想实现此代码,我会将其放在accounts视图集的列表定义或account视图集的常规类中吗。还有我需要的任何导入状态,因为我在
@action
中遇到错误,我链接了文档中有关额外操作的部分。你可以在那里详细阅读。无法创建两个列表操作,因为这些操作仅由方法表示。这意味着在类中有两个名为
list
的方法,您应该已经知道,这在Python上下文和DRF上下文中都是不可能的。如果添加筛选参数(不是url kwarg),它将用于筛选,但不必在
get\u对象中执行此操作。它用于
filter\u queryset
方法。请检查django filter中的django FilterBackend以了解如何在DRF视图中使用筛选器。我不太理解您的第二个问题,但您无法在
列表中定义
get\u对象
。您可以在处理之前更改序列化程序类。我没有看到您在定义的
列表中处理请求。你的第三个问题也令人困惑。有一个视图集同时服务于列表端点和详图端点。那么,您所说的AccountViewSet列表是什么意思?如果您的意思是将其嵌套在
列表
方法中,则不应该。您不应该将任何操作方法嵌套在其他操作方法sok中。非常感谢。问题。。。因此,如果我按照上面的方法进行操作,我将初始化vewset,然后创建列表视图的两个操作。它将检查是否有传递到url末尾的参数。如果是,,