我在Django项目中制作了两种非常基本的帐户类型:讲师和学生。我想要一个已注册教师的电子邮件的列表,以便学生在创建帐户时可以从列表中选择其教师的电子邮件,从而链接两个帐户。
forms.py
class StudentSignUpForm(UserCreationForm):
instructor_id = forms.ModelMultipleChoiceField(queryset=Instructor.objects.all())
class Meta(UserCreationForm):
model = CustomUser
fields = ('username', 'inGameName', 'instructor_id')
help_texts = {
'username': 'Required',
'inGameName': 'Required; A name by which you can be identified',
'instructor_id': 'Optional; Provided by your professor',
}
@transaction.atomic
def save(self):
user = super().save(commit=False)
user.is_student = True
user.save()
student = Student.objects.create(user=user)
student.instructor_id = (self.cleaned_data.get('instructor_id'))
return user
class InstructorSignUpForm(UserCreationForm):
email = forms.EmailField(label='Your Email', help_text='Required')
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = ('username', 'inGameName', 'email')
help_texts = {
'username': 'Required',
'inGameName': 'Required; A name by which you can be identified',
}
@transaction.atomic
def save(self):
user = super().save(commit=False)
user.is_instructor = True
user.email = self.cleaned_data["email"]
user.save()
return user
models.py
class CustomUser(AbstractUser):
is_student = models.BooleanField(default=False)
is_instructor = models.BooleanField(default=False)
username = models.CharField(max_length=40, primary_key=True, default='')
inGameName = models.CharField("In-Game Name", max_length=40, default='')
USERNAME_FIELD = 'username'
class Instructor(models.Model):
user = models.OneToOneField(CustomUser, default ='USER',on_delete=models.CASCADE)
email = models.EmailField(max_length=254, unique=True, default='Email@Email.com')
def __str__(self):
return self.email
class Student(models.Model):
user = models.OneToOneField(CustomUser, default='USER', on_delete=models.CASCADE)
instructor_id = models.ForeignKey(Instructor, to_field='email', on_delete=models.CASCADE, default='Email@Email.com')
/views/students.py
class StudentSignUpView(CreateView):
model = CustomUser
form_class = StudentSignUpForm
template_name = 'student_signup.html'
success_url = reverse_lazy('login')
form = forms.StudentSignUpForm()
form.fields["instructor_id"].queryset = Instructor.objects.all()
/template/student_signup.html
<form method="post" autocomplete="off">
<div class="signup">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create Account</button>
</div>
</form>
我希望讲师电子邮件列表显示在ModelMultipleChoiceField中,但该列表为空。请帮忙!
答案 0 :(得分:0)
我可以在这里看到几个问题。
问题#1
StudentSignUpForm类中的此行指出1名学生可以有多位讲师:
instructor_id = forms.ModelMultipleChoiceField(...
另一方面,“学生”类中的这一行指出,一位学生只能有一位指导员:
instructor_id = models.ForeignKey
您应该在表单中包含form.ModelChoiceField,或者在模型中具有models.ManyToManyField。
问题2
forms.ModelMultipleChoiceField将显示电子邮件作为选择,但默认情况下仍将pk字段用作选择值。若要解决此问题,您应该在定义您的utor_id字段时传递to_field_name ='email'参数(从而更改ModelChoiceField的默认行为),或者在您的学生模型中定义教师_id字段时删除to_field ='email'参数(进行默认设置)与您的模型相关的行为)。我个人更喜欢后者。电子邮件并不是真正的gook外键-它可以更改,您必须同时更新Instructor和Student表才能保持链接。