首页 > 解决方案 > 如何根据用户 ID 过滤 DjangoRestFramework 中的序列化程序?

问题描述

我是django的新手,

我似乎无法找到如何根据请求它并创建 Transaction 对象的用户返回一个 api,你能指导我完成吗?我已阅读内容,但在文档中找不到明确的指南来立即更新序列化程序。

在 laravel 中,我可以这样做:

Transaction::where('user_id', Auth::user()->id)->get();

这是我的序列化器:


class TransactionSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer(read_only=True)
    tags = TagShortSerializer(read_only=True, many=True)

    def get_fields(self, *args, **kwargs):
        # Override this method so that the list of DatabaseUsers presented in the browseable API
        # is restricted to the DatabaseUsers owned by the current user.
        fields = super(TransactionSerializer, self).get_fields(*args, **kwargs)
        view = self.context["view"]
        user = view.request.user
        return Transaction.objects.filter(user=user)

    class Meta:
        model = Transaction
        fields = ["user", "title", "amount", "category", "tags"]

我的观点:


class TransactionViewSet(viewsets.ModelViewSet):
    queryset = Transaction.objects.all()
    serializer_class = TransactionSerializer
    permission_classes = [permissions.IsAuthenticated, IsOwner]

目前它返回: 在此处输入图像描述

完整的追溯:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/transactions/

Django Version: 3.2.5
Python Version: 3.9.5
Installed Applications:
['djmoney',
 'rest_framework',
 'finance.apps.FinanceConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\mixins.py", line 43, in list
    return self.get_paginated_response(serializer.data)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\serializers.py", line 745, in data
    ret = super().data
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\serializers.py", line 246, in data
    self._data = self.to_representation(self.instance)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\serializers.py", line 663, in to_representation
    return [
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\serializers.py", line 664, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\serializers.py", line 500, in to_representation
    for field in fields:
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\serializers.py", line 361, in _readable_fields
    for field in self.fields.values():
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\django\utils\functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "E:\Development\Python\sharkware-api\.venv\lib\site-packages\rest_framework\serializers.py", line 349, in fields
    for key, value in self.get_fields().items():

Exception Type: AttributeError at /transactions/
Exception Value: 'QuerySet' object has no attribute 'items'

标签: python-3.xdjango

解决方案


这不是get_fields. 该方法返回实例化序列化程序时要使用的字段列表。

您想要的是覆盖get_queryset您的视图集:

class TransactionViewSet(viewsets.ModelViewSet):
    queryset = Transaction.objects.all()
    serializer_class = TransactionSerializer
    permission_classes = [permissions.IsAuthenticated, IsOwner]

    def get_queryset(self):
        if self.request.user.is_authenticated:
            return self.queryset.filter(user=self.request.user)
        return Transaction.objects.none()

推荐阅读