Reputation: 316
I have searched all the other threads with similar Questions on this topic but nothing is working. Hoping someone here can help. It only fails when trying to access 'api/orders'.
I am having the following errors
Traceback (most recent call last):
File "C:\Users\projects\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\projects\venv\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\thard\projects\foreside\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\projects\venv\lib\site-packages\rest_framework\viewsets.py", line 114, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\projects\venv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
response = self.handle_exception(exc)
File "C:\Users\projects\venv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\projects\venv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
raise exc
File "C:\Users\projects\venv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\projects\venv\lib\site-packages\rest_framework\mixins.py", line 46, in list
return Response(serializer.data)
File "C:\Users\projects\venv\lib\site-packages\rest_framework\serializers.py", line 760, in data
ret = super().data
File "C:\Users\projects\venv\lib\site-packages\rest_framework\serializers.py", line 260, in data
self._data = self.to_representation(self.instance)
File "C:\Users\projects\venv\lib\site-packages\rest_framework\serializers.py", line 677, in to_representation
return [
Exception Type: TypeError at /api/orders/
Exception Value: 'ModelBase' object is not iterable
Here are the pertinent files
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
ADMIN = 1
APPROVER = 2
TRADER = 3
USER_ROLE_CHOICES = (
(ADMIN, 'admin'),
(APPROVER, 'approver'),
(TRADER, 'trader'),
)
role = models.PositiveSmallIntegerField(choices=USER_ROLE_CHOICES)
REQUIRED_FIELDS = ['role', 'email']
class Meta:
verbose_name = 'user'
verbose_name_plural = 'users'
def get_full_name(self):
return '%s %s' % (self.first_name, self.last_name)
def get_short_name(self):
return self.first_name
def __str__(self):
return self.username
class Order(models.Model):
ADMIN = 1
APPROVER = 2
TRADER = 3
USER_ROLE_CHOICES = (
(ADMIN, 'admin'),
(APPROVER, 'approver'),
(TRADER, 'trader'),
)
name = models.CharField(max_length=50)
order_time = models.DateField(auto_now_add=True)
client = models.CharField(max_length=50)
stock = models.CharField(max_length=10)
qty = models.PositiveIntegerField()
transaction_price = models.FloatField()
payment_method = models.FloatField
settlement = models.DateField(auto_now=True)
status = models.CharField(max_length=50, default="new")
reason = models.CharField(max_length=50, default="new order")
modified_by = models.PositiveSmallIntegerField(choices=USER_ROLE_CHOICES)
REQUIRED_FIELDS = [
'order_time', 'stock', 'qty', 'transaction_price',
'settlement', 'status', 'reason', 'modified_by',
]
class Meta:
verbose_name = 'order'
verbose_name_plural = 'orders'
from rest_framework.routers import DefaultRouter
from django.urls import path, include
from user import views
router = DefaultRouter()
router.register('users', views.UserViewSet, basename='user-list')
router.register('login', views.LoginView, basename='login')
router.register('orders', views.OrderViewSet, basename='order-list')
urlpatterns = [
path('', include(router.urls)),
path('account/logout/', views.LogoutView.as_view(), name='logout')
]
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('user.urls'))
]
# from django.contrib.auth.models import Group
from rest_framework import permissions
ADMIN = 1
APPROVER = 2
TRADER = 3
def _is_in_role(user, role_name):
try:
return user.role == role_name
except:
return None
def _has_role_permission(user, required_roles):
return any([_is_in_role(user, role_name) for role_name in required_roles])
class IsAdminUser(permissions.BasePermission):
required_roles = [ADMIN,]
def has_permission(self, request, view):
has_role_permission = _has_role_permission(request.user, self.required_roles)
return request.user and has_role_permission
def has_object_permission(self, request, view, obj):
has_role_permission = _has_role_permission(request.user, self.required_roles)
return request.user and has_role_permission
class IsAdminOrApproverUser(permissions.BasePermission):
required_roles = [ADMIN, APPROVER,]
def has_permission(self, request, view):
has_role_permission = _has_role_permission(request.user, self.required_roles)
return request.user and has_role_permission
def has_object_permission(self, request, view, obj):
has_role_permission = _has_role_permission(request.user, self.required_roles)
return request.user and has_role_permission
class IsAdminOrTraderUser(permissions.BasePermission):
required_roles = [ADMIN, TRADER,]
def has_permission(self, request, view):
has_role_permission = _has_role_permission(request.user, self.required_roles)
return request.user and has_role_permission
def has_object_permission(self, request, view, obj):
has_role_permission = _has_role_permission(request.user, self.required_roles)
return request.user and has_role_permission
from rest_framework.serializers import ModelSerializer
from user.models import User, Order
class UserSerializer(ModelSerializer):
class Meta:
fields = ('id', 'first_name', 'last_name', 'username', 'password', 'role', 'email')
model = User
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User.objects.create(**validated_data)
user.set_password(validated_data['password'])
user.is_staff = True
user.save()
return user
class OrderSerializer(ModelSerializer):
class Meta:
fields = (
'id', 'name', 'order_time', 'client',
'stock', 'qty', 'transaction_price', 'payment_method', 'settlement',
'status', 'reason', 'modified_by',
)
model = Order
pertinent parts of settings.py
...
INSTALLED_APPS = [
...,
'rest_framework',
'rest_framework.authtoken',
'user',
]
AUTH_USER_MODEL = 'user.User'
...
from django.shortcuts import render
from rest_framework import status
from rest_framework.authentication import TokenAuthentication
from rest_framework.authtoken.serializers import AuthTokenSerializer
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet, ModelViewSet
from rest_framework.permissions import AllowAny
from user.permissions import IsAdminUser, IsAdminOrApproverUser, IsAdminOrTraderUser
from user.models import User, Order
from user.serializers import UserSerializer, OrderSerializer
class UserViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
authentication_classes = [TokenAuthentication]
def get_permissions(self):
permission_classes = []
if self.action == 'create':
permission_classes = [IsAdminUser]
elif self.action == 'list':
permission_classes = [IsAdminUser]
elif self.action == 'retrieve' or self.action == 'update' or self.action == 'partial_update':
permission_classes = [IsAdminUser]
elif self.action == 'destroy':
permission_classes = [IsAdminUser]
return [permission() for permission in permission_classes]
class LoginView(ViewSet):
serializer_class = AuthTokenSerializer
def create(self, request):
return ObtainAuthToken().post(request)
class LogoutView(APIView):
def get(self, request, format=None):
request.user.auth_token.delete()
return Response(status=status.HTTP_200_OK)
class OrderViewSet(ModelViewSet):
queryset = Order
serializer_class = OrderSerializer
authentication_classes = [TokenAuthentication]
def get_permissions(self):
permission_classes = []
if self.action == 'create':
permission_classes = [IsAdminOrTraderUser]
elif self.action == 'list':
permission_classes = [IsAdminOrTraderUser]
elif self.action == 'retrieve' or self.action == 'update':
permission_classes = [IsAdminOrTraderUser]
elif self.action == 'partial_update':
permission_classes = [IsAdminOrApproverUser]
elif self.action == 'destroy':
permission_classes = [IsAdminUser]
return [permission() for permission in permission_classes]
. .
Upvotes: 0
Views: 8868
Reputation: 79
You don't define a direct model name to the queryset it will raise an error
queryset = Order //(it is a wrong way),
The right way is to define query set
queryset = Order.objects.all()
Upvotes: 1
Reputation: 88509
The queryset
attribute must be a QuerySet
rather than a model class
class OrderViewSet(ModelViewSet):
queryset = Order.objects.all()
# rest of your code
Upvotes: 5