9

Snippet モデルを独自のカスタム User モデルに置き換えることを除いて、django REST フレームワークのチュートリアルを進めています。ただし、API をテストしようとすると、取得し続けます。

Traceback (most recent call last):
  File "/Users/AndyFang/Desktop/doorstep-django/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/Users/AndyFang/Desktop/doorstep-django/venv/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/AndyFang/Desktop/doorstep-django/venv/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 77, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/AndyFang/Desktop/doorstep-django/venv/lib/python2.7/site-packages/rest_framework/views.py", line 326, in dispatch
    response = self.handle_exception(exc)
  File "/Users/AndyFang/Desktop/doorstep-django/venv/lib/python2.7/site-packages/rest_framework/views.py", line 314, in dispatch
    self.initial(request, *args, **kwargs)
  File "/Users/AndyFang/Desktop/doorstep-django/venv/lib/python2.7/site-packages/rest_framework/views.py", line 235, in initial
    self.check_permissions(request)
  File "/Users/AndyFang/Desktop/doorstep-django/venv/lib/python2.7/site-packages/rest_framework/views.py", line 192, in check_permissions
    if not permission.has_permission(request, self):
  File "/Users/AndyFang/Desktop/doorstep-django/venv/lib/python2.7/site-packages/rest_framework/permissions.py", line 131, in has_permission
    if model_cls is None and getattr(view, '_ignore_model_permissions'):
AttributeError: 'user_list' object has no attribute '_ignore_model_permissions'

これを修正するためにさまざまなことを試みました(フォーマット機能の無効化、csrf_exmept トークンの追加など)がすべて役に立ちませんでした。以下は私が書いたコードです:

serializers.py

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

ビュー.py

@api_view(['GET', 'POST'])
def user_list(request, format=None):
  """
  List all users, or create a new user.
  """
  if request.method == 'GET':
    users = User.objects.all()
    serializer = UserSerializer(users, many=True)
    return Response(serializer.data)

  elif request.method == 'POST':
    serializer = UserSerializer(data=request.DATA)
    if serializer.is_valid():
      serializer.save()
      return Response(serializer.data, status=status.HTTP_201_CREATED)
    else:
      return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
def user_detail(request, pk, format=None):
  """
  Retrieve, update or delete a user instance.
  """              
  try:
    user = User.objects.get(pk=pk)
  except User.DoesNotExist:
    return Response(status=status.HTTP_404_NOT_FOUND)

  if request.method == 'GET':
    serializer = UserSerializer(user)
    return Response(serializer.data)

  elif request.method == 'PUT':
    serializer = UserSerializer(user, data=request.DATA)
    if serializer.is_valid():
      serializer.save()
      return Response(serializer.data)
    else:
      return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

  elif request.method == 'DELETE':
    user.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

urls.py

4

4 に答える 4

8

これはちょっとしたバグです。そこで AttributeError を発生させるべきではありません。マスターで修正したところです。

代わりに、master に対して実行すると、次のアサーション エラーが表示されます。

Cannot apply DjangoModelPermissions on a view that does not have `.model` or `.queryset` property.

ここでの問題はDjangoModelPermissions、ビューに必要なモデル権限を決定する方法がある場合にのみクラスが機能することです。そのパーミッション クラスを使用する場合は、ビューをクラス ベースのビューとして書き直し、model属性が適切に設定されていることを確認する必要があります。

それらをクラスベースのビューとして書き直したからといって、ジェネリッククラスベースのビューを使用する必要があるわけではないことに注意してください。現在持っている明示的なビューロジックを引き続き保持できます。このようなもの:

class UserListView(views.APIView):
    queryset = User.objects.all()

    def get(self, request, format=None):
        users = self.queryset
        serializer = UserSerializer(users, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):     
        serializer = UserSerializer(data=request.DATA)
        if serializer.is_valid():
          serializer.save()
          return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
          return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class UserDetailView(views.APIView):
    queryset = User.objects.all()

    def get_object(self, pk)
        try:
            return self.queryset.get(pk=pk)
        except User.DoesNotExist:
            raise Http404

    def get(self, request, pk, format=None):
        user = self.get_object(pk)
        serializer = UserSerializer(user)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        user = self.get_object(pk)
        serializer = UserSerializer(user, data=request.DATA)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        user = self.get_object(pk)
        user.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

querysetどちらの場合も を使用するとDjangoModelPermissions、これらのビューに を適用できるようになることに注意してください。

于 2013-06-18T10:22:04.480 に答える
5

おそらく、DjangoModelPermissions設定のデフォルトのアクセス許可クラスとして、または同様のセットを持っているでしょう。何かのようなもの:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
    )
}

これはデフォルトで、ビューが基づいているモデルに対する権限をユーザーが持っているかどうかをチェックします。ビューにモデルが設定されていない場合、アクセス許可を見つけることができません。そのため、ビューにモデルを設定する必要があります。これは、クラスベースの APIView でのみ可能であることがわかる限りです。

from .models import MyModel

class MyView(APIView):

    model = MyModel

    def get(self, request, pk):
        # ...

ビューが Django モデルに基づいていない場合は、このデフォルト クラスをREST_FRAMEWORK設定から削除するか、次のようにビューにカスタム パーミッション クラスを設定できます。

from rest_framework import permissions

class MyView(APIView)

    permission_classes = (permissions.IsAuthenticated,)

    def get(self, request, pk):
        # ...

または、次のような関数ベースのビューで:

from rest_framework import permissions

@api_view(['GET', 'POST'])
@permission_classes((permissions.IsAuthenticated,))
def my_view(request)
    # ...

アクセス許可の詳細については、http://django-rest-framework.org/api-guide/permissions.htmlを参照してください。

于 2013-07-31T12:48:15.207 に答える
2

これは最も簡単です:

 @api_view(['POST'])
 @permission_classes((permissions.AllowAny,))
 def my_view(request)
 # ...
于 2014-03-14T12:50:43.853 に答える
0

私はかなり初心者なので、ビューを書き直すのではなく、現時点で残りのフレームワークのチュートリアルも行っています。 フレームワークの settings.py のアクセス許可設定を以下に変更しました。モデルからの権限。

'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
于 2013-12-29T03:43:38.807 に答える