[英]Django User model saves twice into database
我正在尝试使用 Django 创建多用户注册系统。 但是,每当我调用save()
方法来保存 User 类型时,它都会两次保存到 User 表中。 保存的第二个 model 的有趣之处在于许多必填字段为空。
我正在使用从AbstractBaseUser
创建的自定义用户 model 。 我还为 CustomUser model 重写了 forms。 对于多种用户类型,我使用的是配置文件 model(学生 model 对用户模型有一个 OneToOne 字段)
模型.py :
class User(AbstractBaseUser, PermissionsMixin):
# I've removed some unimportant code here
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
class Types(models.TextChoices):
STUDENT = 'STUDENT', 'Student'
DEPARTMENT_USER = 'DEPARTMENT_USER', 'Department user'
ADMIN = 'ADMIN', 'Admin'
user_type = models.CharField(_('Type'), max_length=50, choices=Types.choices, default=Types.STUDENT)
first_name = models.CharField(_('First name'), max_length=70, blank=False, default="")
middle_name = models.CharField(_('Middle name'), max_length=70, blank=True, default="")
last_name = models.CharField(_('Last name'), max_length=70, blank=False, default="")
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False) # a admin user; non super-user
is_superuser = models.BooleanField(default=False) # a superuser
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = ['user_type', 'first_name', 'last_name'] # Email & Password are required by default.
objects = UserManager()
class Meta:
verbose_name = ('user')
verbose_name_plural = ('users')
#db_table = 'auth_user'
abstract = False
class AccountConfirmed(models.Model):
# Model to determine which users have confirmed their email addresses.
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='accountconfirmed')
email_confirmed = models.BooleanField(default=False)
reset_password = models.BooleanField(default=False)
class Meta:
app_label = 'auth'
# When the user model is created, through signals an AccountConfirmed model is also created.
# The email_confirmed and reset_password field is set to false.
@receiver(models.signals.post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
AccountConfirmed.objects.create(user=instance)
instance.accountconfirmed.save()
######################################################
######################################################
class Student(User):
# This is the model class for students
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='students')
matric_number = models.CharField(_('Matriculation number'), max_length=11, blank=False)
department = models.CharField(_('Department'), max_length=40, blank=False)
# has_graduated, level, etc. future possibilities
def __str__(self):
return f'{self.user.email}'
forms.py :
class StudentSignupForm(UserCreationForm):
# first_name = forms.CharField(max_length=70)
# middle_name = forms.CharField(max_length=70, required=False)
# last_name = forms.CharField(max_length=70)
matric_number = forms.CharField(min_length=10, max_length=11, help_text='Your Matric number must be 10 characters')
department = forms.CharField(max_length=40, help_text='e.g Computer Science')
class Meta(UserCreationForm.Meta):
model = User
fields = UserCreationForm.Meta.fields + ('matric_number', 'department')
@transaction.atomic
def save(self, commit=True):
# Save the User instance and get a reference to it
user = super().save(commit=False)
user.user_type = User.Types.STUDENT
user.is_active = False
#if commit:
user.save()
print(f' forms.py {user.email} {user.first_name}')
student = Student.objects.create(user=user, matric_number=self.cleaned_data.get('matric_number'), department=self.cleaned_data.get('department'))
# Add other details
# Return User instance, not Student instance
return user
视图.py :
class StudentUserSignupView(CreateView):
model = User
template_name = 'account/signup.html'
form_class = StudentSignupForm
def get_context_data(self, **kwargs):
kwargs['user_type'] = 'STUDENT'
return super().get_context_data(**kwargs)
def form_valid(self, form):
user = form.save()
#login(self.request, user)
send_verification_mail(self, user)
return redirect('verification_sent')
那么如何更正用户表中的多次保存呢? 此外,如何在大部分必填字段为空的情况下保存 model?
正如@RaghavKundra 所指出的,下面的行是导致多次保存到数据库的问题的原因
class Student(User):
相反,它应该是class Student(models.Model):
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.