Как управлять и регистрировать различные типы пользователей с различными полями и профилями в Django?

BACKGROUND

Я работаю над проектом интеграции Django и NextJS с использованием Django REST-API Framework. Я настроил модель пользователя по умолчанию, создав пользовательскую модель пользователя, где адрес электронной почты является уникальным и основным полем.

В моем проекте есть 3 различных типа пользователей: Client, Student и Teacher. В моем файле пользовательских моделей учетных записей пользователей я установил флаг is_usertype для каждого типа пользователя; например: is_client, is_student, is_teacher. Каждый тип пользователя (Клиент, Студент, Преподаватель) имеет различные профили, содержащие различные поля.

Дополнительные поля для каждого типа пользователя следующие:

  1. Client Profile: country
  2. Student Profile: interests
  3. Teacher Profile: bio

У меня есть одна общая конечная точка API регистрации пользователя для всех типов пользователей, которая называется http://127.0.0.1:8000/user-api/register. Во время регистрации пользователя конкретный тип пользователя устанавливается в True. Например, если я пытаюсь зарегистрировать пользователя типа Клиент, мне нужно установить флаг is_client в значение True, для пользователя типа Студент мне нужно установить флаг is_student в значение True и для пользователя типа Преподаватель мне нужно установить флаг is_teacher в значение True.

Когда я пытаюсь зарегистрировать определенный тип пользователя, тип пользователя не регистрируется. Я использую Postman для тестирования конечных точек регистрации типов пользователей и использую панель управления Django Admin для проверки того, регистрируются ли данные типа пользователя в базе данных.

PROBLEM

Я не могу зарегистрировать различные типы пользователей (клиент, студент, преподаватель) и создать профили в моей системе.

CODES

managers.py

Этот файл содержит функции менеджера моделей для каждого типа пользователей (Клиенты, Студенты, Учитель, Нормальные пользователи и Суперпользователи)

from django.contrib.auth.models import BaseUserManager

from django.apps import apps

"""
Custom User Account Model Manager
Email is the unique identifier for authentication instead of username
"""


class UserAccountManager(BaseUserManager):
    """
        Create and save a User with the given email, full name and password
    """

    def create_user(self, email, full_name, password=None):
        if not email:
            raise ValueError("Users must have an email address")

        if not full_name:
            raise ValueError("Users must have a name")

        email = self.normalize_email(email)
        email = email.lower()

        user_account = self.model(email=email, full_name=full_name, )

        user_account.set_password(password)

        user_account.save(using=self._db)

        return user_account

    """
        Create and save a SuperUser with the given email, full name and password
    """

    def create_superuser(self, email, full_name, password):

        user_account = self.create_user(email, full_name, password, )

        user_account.is_admin = True
        user_account.is_staff = True
        user_account.is_superuser = True

        user_account.save(using=self._db)

        return user_account

    """
        Create and save a Client with the given email, full name and password
    """

    def create_client(self, email, full_name, country, password=None, **kwargs):

        ClientProfile = apps.get_model("user_app", "ClientProfile")

        client = self.create_user(email, full_name, password, **kwargs)

        client.is_client = True

        clientProfile = ClientProfile(
            client=client, country=country, is_client=True)

        clientProfile.save(using=self._db)

        return client

    """
        Create and save a Student with the given email, full name and password
    """

    def create_student(self, email, full_name, interests, password=None, **kwargs):

        StudentProfile = apps.get_model("user_app", "StudentProfile")

        student = self.create_user(email, full_name, password, **kwargs)

        student.is_student = True

        studentProfile = StudentProfile(
            student=student, interests=interests, is_student=True)

        studentProfile.save(using=self._db)

        return student

    """
        Create and save a Teacher with the given email, full name and password
    """

    def create_teacher(self, email, full_name, bio, password=None, **kwargs):

        TeacherProfile = apps.get_model("user_app", "TeacherProfile")

        teacher = self.create_user(email, full_name, password, **kwargs)

        teacher.is_teacher = True

        teacherProfile = TeacherProfile(
            teacher=teacher, bio=bio, is_teacher=True)

        teacherProfile.save(using=self._db)

        return teacher

models.py

Этот файл включает Custom User Account Model, Client User Type Profile Model, Student User Type Profile Model, Teacher User Type Profile Model.

views.py

Этот файл содержит представления конечных точек User API. Я столкнулся с проблемой в UserAccountRegistrationView. Когда я пытаюсь зарегистрировать определенный тип пользователя с помощью Postman, он дает мне ответ ERROR

"error" : "Something went wrong when registering User Account!"

Я хочу использовать этот APIView Response для моей конфигурации фронтенда в NextJS, поскольку это требование.

user_app_urls.py

Этот файл содержит конечные точки URL API пользовательского приложения.

# URL Pattern Listing
# Application : User

from django.urls import path

from .views import UserAccountAPIOverview, UserAccountRegistrationView

urlpatterns = [
    path('', UserAccountAPIOverview.as_view()),
    path("register", UserAccountRegistrationView.as_view()),
]

admin.py

Этот файл содержит конфигурацию панели управления Django Admin для каждой модели (UserAccount, Client Profile, Student Profile, Teacher Profile).

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as AbstractBaseUserAdmin

from .models import StudentProfile, TeacherProfile, UserAccount, ClientProfile

from django.contrib.admin import ModelAdmin

# User Account Admin


class UserAccountAdmin(AbstractBaseUserAdmin):

    model = UserAccount

    list_display = ("email", "full_name", "date_joined",
                    "last_login", "is_admin", "is_staff", "is_client", "is_student", "is_teacher", )
    search_fields = ("email", "full_name",)
    readonly_fields = ("id", "date_joined", "last_login",)
    ordering = ("email",)

    filter_horizontal = ()
    list_filter = ("email", "full_name", "is_admin", "is_staff", "is_active", )

    fieldsets = (
        (None, {
            "fields": (
                "email",
                "full_name",
                "password",
            )
        }),
        ("Permissions", {
            "fields": (
                "is_staff",
                "is_active",
            )
        }),
    )

    add_fieldsets = (
        (None, {
            "classes": ("wide",),
            "fields": (
                "email",
                "full_name",
                "password1",
                "password2",
                "is_staff",
                "is_active",
            )
        }),
    )


class ClientProfileAdmin(ModelAdmin):

    class Meta:
        model = ClientProfile

    list_display = ("client", "get_email", "get_dateJoined",
                    "get_lastLoggedIn", "country", )


class StudentProfileAdmin(ModelAdmin):
    class Meta:
        model = StudentProfile

    list_display = ("student", "get_email", "get_dateJoined",
                    "get_lastLoggedIn", "interests", )


class TeacherProfileAdmin(ModelAdmin):

    class Meta:
        model = TeacherProfile

    list_display = ("teacher", "get_email", "get_dateJoined",
                    "get_lastLoggedIn", "bio", )


admin.site.register(UserAccount, UserAccountAdmin)
admin.site.register(ClientProfile, ClientProfileAdmin)
admin.site.register(StudentProfile, StudentProfileAdmin)
admin.site.register(TeacherProfile, TeacherProfileAdmin)

После запуска сервера и выполнения Postman для тестирования конечных точек API регистрации пользователей для различных типов пользователей, как показано ниже, я получаю следующую ошибку:

"error" : "Something went wrong when registering User Account!"

Конечная точка API регистрации типа пользователя клиента Client User Type Registration API Endpoint

Конечная точка API регистрации типа пользователя студента Student User Type Registration API Endpoint

Конечная точка API регистрации типа пользователя учителя Teacher User Type Registration API Endpoint

Вы получаете исключение из-за keyError, для этих строк,

            is_student = data["is_student"]
            is_teacher = data["is_teacher"]

Вы публикуете 'is_client', но два других параметра в данных остаются пустыми. Они не существуют в переменной data, так как не публикуются postman'ом. Что вы можете сделать, так это попробовать

            is_student = data.get("is_student", None)

методget присвоит None, если ключ "is_student" не найден в request.data и keyError не возникнет.

Вернуться на верх