Djoser UserViewSet, getting 401 Unauthorized `as_view("get": "list")`

64 views Asked by At

When I utilize POSTMAN to test the endpoint, I encounter a 401 Unauthorized error. I would greatly appreciate your assistance in comprehending the nature of the issue that has caused this unauthorized access error to occur.

{ "detail": "Authentication credentials were not provided." }

accounts.views.py

 from djoser.views import UserViewSet
    from .serializers import UserCreateSerializer
    from .models import AddressDetails, UserProfile
    from rest_framework import status
    from rest_framework.response import Response

     # Create your views here.
     class UserCreateView(UserViewSet):
     serializer_class = UserCreateSerializer

     def create(self, request, *args, **kwargs):
        # Extract user account data from the request
        user_data = {
            "email": request.data.get("email"),
            "user_role": request.data.get("user_role"),
            "password": request.data.get("password"),
        }

        # Create a user account
        user_serializer = UserCreateSerializer(data=user_data)
        if user_serializer.is_valid():
            user = user_serializer.save()
        else:
            return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        # Extract and create AddressDetails data
        address_data = {
            "address_line_one": request.data.get("address_line_one"),
            "address_line_two": request.data.get("address_line_two"),
            "address_line_three": request.data.get("address_line_three"),
            "province": request.data.get("province"),
            "barangay": request.data.get("barangay"),
            "city": request.data.get("city"),
            "zip_code": request.data.get("zip_code"),
        }
        AddressDetails.objects.create(**address_data)

        # Extract and create UserProfile data
        profile_data = {
            "user": user,
            "first_name": request.data.get("first_name"),
            "middle_name": request.data.get("middle_name"),
            "last_name": request.data.get("last_name"),
            "date_of_birth": request.data.get("date_of_birth"),
            "gender": request.data.get("gender"),
            "relationship_status": request.data.get("relationship_status"),
            "phone_number": request.data.get("phone_number"),
            "address_details": address_data, 
        }
        UserProfile.objects.create(**profile_data)

        return Response(data, status=status.HTTP_201_CREATED)

config.urls.py

from django.contrib import admin
from django.urls import path, include, re_path
from accounts.views import UserCreateView

# drf yasg
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
    openapi.Info(
        title="Djoser API",
        default_version="v1",
        description="REST implementation of Django authentication system. djoser library provides a set of Django Rest Framework views to handle basic actions such as registration, login, logout, password reset and account activation. It works with custom user model.",
        contact=openapi.Contact(email="[email protected]"),
        license=openapi.License(name="BSD License"),
    ),
    public=True,
    permission_classes=(permissions.AllowAny,),
)

urlpatterns = [
    path("api/v1/users/", UserCreateView.as_view({"get": "list"}), name="user-create"),
    path('admin/', admin.site.urls),
    re_path(r"^api/v1/docs/$",
    schema_view.with_ui("swagger", cache_timeout=0),
    name="schema-swagger-ui",
    ),
    path("api/v1/", include("accounts.urls")),
    path("api/v1/", include("djoser.urls")),
    path("api/v1/", include("djoser.urls.authtoken")),
]

accounts.serializers.py

   from djoser.serializers import UserCreateSerializer
from django.contrib.auth import get_user_model
from rest_framework import serializers
from phonenumber_field.modelfields import PhoneNumberField #type: ignore

User = get_user_model()

class UserCreateSerializer(UserCreateSerializer):
    first_name = serializers.CharField(max_length=150,)
    middle_name = serializers.CharField(max_length=150,)
    last_name = serializers.CharField(max_length=150,)
    date_of_birth = serializers.DateField()
    gender = serializers.CharField(max_length=1,)
    relationship_status = serializers.CharField(max_length=150,)
    phone_number = serializers.CharField(max_length=150,)

    address_line_one = serializers.CharField(max_length=150,)
    address_line_two = serializers.CharField(max_length=150,)
    address_line_three = serializers.CharField(max_length=150,)
    province = serializers.CharField(max_length=150,)
    barangay = serializers.CharField(max_length=150,)
    city = serializers.CharField(max_length=150,)
    zip_code = serializers.CharField(max_length=150,)

    class Meta(UserCreateSerializer.Meta):
        model = User
        fields = (
            "id",
            "email",
            "user_role",
            "password",
            "first_name",
            "middle_name",
            "last_name",
            "date_of_birth",
            "gender",
            "relationship_status",
            "phone_number",
            "address_line_one",
            "address_line_two",
            "address_line_three",
            "province",
            "barangay",
            "city",
            "zip_code"
        )

config.settings.py

"""
Django settings for config project.

Generated by 'django-admin startproject' using Django 4.2.

For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-a+!z_4han7cjf)#3n1qf*7tn_&bc79p**abob#sa7_m_5kj3@e'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

DJANGO_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

PROJECT_APPS = [
    "accounts",
]

THIRD_PARTY_APPS = [
    'rest_framework',
    'rest_framework.authtoken',
    'drf_yasg',
    'djoser',
    'phonenumber_field',
    'corsheaders',
]

INSTALLED_APPS = DJANGO_APPS + PROJECT_APPS + THIRD_PARTY_APPS

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware', # middleware for cors-headers
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'config.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'config.wsgi.application'


# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db_healthwatch',
        'USER': 'root',
        'PASSWORD': 'password1',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}


# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# Django Custom User Model
AUTH_USER_MODEL = "accounts.UserAccount"

# django-phonenumber-field configuration
PHONENUMBER_DB_FORMAT = "NATIONAL"
PHONENUMBER_DEFAULT_REGION = "PH"

# authentication scheme configuration
REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework.authentication.TokenAuthentication",
    ),
}

# djoser configuration
DJOSER = {
    "USER_CREATE_PASSWORD_RETYPE": True,
    "USERNAME_CHANGED_EMAIL_CONFIRMATION": True,
    "PASSWORD_CHANGED_EMAIL_CONFIRMATION": True,
    "SEND_CONFIRMATION_EMAIL": True,
    "SET_USERNAME_RETYPE": True,
    "SET_PASSWORD_RETYPE": True,
    "PASSWORD_RESET_CONFIRM_URL": "password/reset/confirm/{uid}/{token}",
    "USERNAME_RESET_CONFIRM_URL": "email/reset/confirm/{uid}/{token}",
    "ACTIVATION_URL": "activate/{uid}/{token}",
    "SEND_ACTIVATION_EMAIL": True,
    "SERIALIZERS": {
        "user_create": "accounts.serializers.UserCreateSerializer", # custom serializer
        "user": "djoser.serializers.UserSerializer",
        "current_user": "djoser.serializers.UserSerializer",
        "user_delete": "djoser.serializers.UserSerializer",
    },
}

# cors headers configuration
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

# email configuration
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
EMAIL_HOST = "localhost"
EMAIL_PORT = "1025"
EMAIL_HOST_USER = ""
EMAIL_HOST_PASSWORD = ""
EMAIL_USE_TLS = False
0

There are 0 answers