我是 Django 新手,我正在按照教程创建学校系统。我有一个
CustomUser
,通过 OneToOneField()
与三个不同的表相关,在注册用户时,根据类型(HOD、教师、学生),我使用 @receiver
创建两个信号来创建一个实例POST
请求,然后将其保存在各自的表中。
问题:
CustomUser
对象并调用我保存在用户变量中的 create_user()
类,但是当我使用该对象保存我需要的表中的其他数据时(此中的教师)情况)用户未创建:def create_teachers(request):
if auth_user(request) == True:
# Do something for authenticated users.
if request.method == 'GET':
return render(request, 'create_teachers.html')
else:
try:
user = CustomUser.objects.create_user(
password='defaultPass',
first_name=request.POST.get('first_name'),
last_name=request.POST.get('last_name'),
email=request.POST.get('email'),
user_type=2,
)
user.Teachers.address=request.POST.get('address')
user.save()
print('Professor created successfully')
return redirect('/auth/create_teachers')
except:
print('Error creating teacher')
return redirect('/auth/create_teachers')
else:
return redirect('../login')
Error creating teacher
[27/Sep/2024 13:46:14] "POST /auth/create_teachers HTTP/1.1" 302 0
[27/Sep/2024 13:46:14] "GET /auth/create_teachers HTTP/1.1" 200 34724
[27/Sep/2024 13:46:14] "GET /static/css/dist/styles.css?v=1727459174 HTTP/1.1" 200 54543
# admin.py
class UserAdmin(BaseUserAdmin):
ordering = ('email',)
admin.site.register(CustomUser, UserAdmin)
# managers.py
class CustomUserManager(BaseUserManager):
"""
Custom user model manager where email is the unique identifiers
for authentication instead of usernames.
"""
def create_user(self, email, password, **extra_fields):
"""
Create and save a user with the given email and password.
"""
if not email:
raise ValueError(_("The Email must be set"))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
"""
Create and save a SuperUser with the given email and password.
"""
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", True)
if extra_fields.get("is_staff") is not True:
raise ValueError(_("Superuser must have is_staff=True."))
if extra_fields.get("is_superuser") is not True:
raise ValueError(_("Superuser must have is_superuser=True."))
return self.create_user(email, password, **extra_fields)
# models.py
class CustomUser(AbstractUser):
username = None
email = models.EmailField(_("email address"), unique=True)
user_type_data=((1,'HOD'),(2,'staff'),(3,'users'))
user_type=models.CharField(default=1,choices=user_type_data,max_length=10)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
class AdminHOD(models.Model):
id=models.AutoField(primary_key=True)
admin=models.OneToOneField(CustomUser,on_delete=models.CASCADE)
created_at=models.DateTimeField(auto_now_add=True)
updated_at=models.DateTimeField(auto_now_add=True)
objects=models.Manager()
class Teachers(models.Model):
id=models.AutoField(primary_key=True)
admin=models.OneToOneField(CustomUser,on_delete=models.CASCADE)
phone=PhoneNumberField()
address=models.TextField()
course_id=models.ManyToManyField(Courses)
subject_id=models.ManyToManyField(Subjects)
section_id=models.ManyToManyField(Sections)
created_at=models.DateTimeField(auto_now_add=True)
updated_at=models.DateTimeField(auto_now_add=True)
class Students(models.Model):
id=models.AutoField(primary_key=True)
admin=models.OneToOneField(CustomUser,on_delete=models.CASCADE)
idCard=models.PositiveIntegerField(unique=True)
age=models.PositiveSmallIntegerField()
gender=models.CharField(max_length=255,)
phone=PhoneNumberField()
address=models.TextField()
profile_pic=models.FileField()
session_start=models.DateField()
session_end=models.DateField()
course_id=models.ForeignKey(Courses,on_delete=models.SET_DEFAULT, default=1)
sections_id=models.ForeignKey(Sections,on_delete=models.SET_DEFAULT, default=1)
created_at=models.DateTimeField(auto_now_add=True)
updated_at=models.DateTimeField(auto_now_add=True)
# Receive a signal to create a new user with certain type
@receiver(post_save,sender=CustomUser)
def create_user_profile(sender,instance,created,**kwargs):
if created:
if instance.user_type == 1:
AdminHOD.objects.create(admin=instance)
if instance.user_type == 2:
Teachers.objects.create(admin=instance)
if instance.user_type == 3:
Students.objects.create(admin=instance)
# Save the user
@receiver(post_save,sender=CustomUser)
def save_user_profile(sender,instance,**kwargs):
if instance.user_type == 1:
instance.adminhod.save()
if instance.user_type == 2:
instance.teachers.save()
if instance.user_type == 3:
instance.students.save()
如果我注释掉行
user.Teachers.address=request.POST.get('address')
,则创建用户不会出现任何问题,并且创建 Teachers
表中的实例,且地址字段为空。
我需要的是了解错误发生的原因以及如何修复它。我曾考虑过为每个表创建一个自定义模型,而不是使用
CustomUser
并随后引用其他表,但我不知道该解决方案有多优化。也欢迎任何改进代码的建议。谢谢
编辑:回溯。
对于我的回答,我将
Teachers
模型重命名为 Teacher
,因为在这种情况下使用复数表名称会变得非常混乱。
related_name
:
# the default related name for a `OneToOneField` is the lowercase name of the model
class Teacher(models.Model):
id=models.AutoField(primary_key=True)
admin=models.OneToOneField(
CustomUser,
on_delete=models.CASCADE,
related_name='teacher'
)
...
现在在您的视图中,您可以使用
Teacher
:创建相关的
related_name
对象
user.teacher.address=request.POST.get('address')