Django:不填充formsModelMultipleChoiceField数据

时间:2019-04-12 22:46:21

标签: django django-models django-forms django-templates django-views

我在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中,但该列表为空。请帮忙!

1 个答案:

答案 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表才能保持链接。