0

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

users.models.py

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'

user.urls.py

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')
]

project.urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('user.urls'))
]

user.permissions.py

# 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

users.serializers.py

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'
...

user.views.py

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]

. .

3
  • Can you share the code regarding ModelBase? Commented Aug 12, 2020 at 11:00
  • @ruddra I am not sure where to find ModelBase, but it's in Django somewhere, nothing I wrote. Any suggestions where I could find it and I can update my question with that info. Commented Aug 12, 2020 at 11:04
  • It would be helpful to see the view file that contains the ViewSets, as referenced in user.views.py from user import views Commented Aug 12, 2020 at 11:04

2 Answers 2

5

The queryset attribute must be a QuerySet rather than a model class

class OrderViewSet(ModelViewSet):
    queryset = Order.objects.all()
    # rest of your code
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. I can't believe I had to post a question to catch a minor typo. I've been up too long working on this project. Now I can move forward.
1

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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.