Как управлять и регистрировать различные типы пользователей с различными полями и профилями в Django?
【BACKGROUND】
Я работаю над проектом интеграции Django и NextJS с использованием Django REST-API Framework. Я настроил модель пользователя по умолчанию, создав пользовательскую модель пользователя, где адрес электронной почты является уникальным и основным полем.
В моем проекте есть 3 различных типа пользователей: Client, Student и Teacher. В моем файле пользовательских моделей учетных записей пользователей я установил флаг is_usertype
для каждого типа пользователя; например: is_client
, is_student
, is_teacher
. Каждый тип пользователя (Клиент, Студент, Преподаватель) имеет различные профили, содержащие различные поля.
Дополнительные поля для каждого типа пользователя следующие:
- Client Profile:
country
- Student Profile:
interests
- 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 регистрации типа пользователя клиента
Конечная точка API регистрации типа пользователя студента
Конечная точка API регистрации типа пользователя учителя
Вы получаете исключение из-за 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 не возникнет.