如何通过ModelForm ForeignKey创建模型对象?

时间:2017-08-03 01:37:32

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

我有一个课堂和学生模型,如下所示

class Classroom(models.Model):
    COURSE_NAME = (
        ('MA8', 'Math 8'),
        ('SC10', 'Science 10'),
        ('PH11', 'Physics 11'),
        ('PH12', 'Physics 12'),
    )
    BLOCK_NUMBER = (
        ('11', 'Block 1-1'),
        ('12', 'Block 1-2'),
        ('13', 'Block 1-3'),
        ('14', 'Block 1-4'),
        ('21', 'Block 2-1'),
        ('22', 'Block 2-2'),
        ('23', 'Block 2-3'),
        ('24', 'Block 2-4'),
    )
    class_list = models.TextField()
    course_name = models.CharField(max_length=20, choices=COURSE_NAME)
    course_block = models.CharField(max_length=10, choices=BLOCK_NUMBER)


class Student(models.Model):
    classroom = models.ForeignKey(Classroom, on_delete=models.CASCADE)
    nickname = models.CharField(default='JohnS', max_length=31)
    attend = models.BooleanField(default=True)

我为Classroom创建了一个表单。class_list和TextField是用户复制/粘贴名称列表的地方。我想解析class_list并将每个个人名称保存为nickname。我首先尝试了以下内容,但这似乎并没有保存Student对象。

forms.py
class ClassroomForm(ModelForm):
    class Meta:
        model = Classroom
        fields = ['course_name', 'course_block','class_list']

views.py
class ClassroomCreateView(CreateView):
    model = Classroom
    form_class = ClassroomForm

    def form_valid(self, form):
        classroom = form.save(commit=False)
        s = Student()
        for line in classroom.class_list:
            s.nickname = line
            s.save()
        classroom.save()
        return super(ClassroomCreateView, self).form_valid(form)
    def get_success_url(self):
        return reverse('classroom:submitted')

我还尝试创建StudentForm,允许用户选择course_namecourse_block(对应于特定的class_list)。然后,表单或视图将创建单个Student对象并显示它们。我读到了关于ModelChoiceField但我无法弄清楚如何实现它。

我如何以及在何处(自动)从ForeignKey字段创建Student对象?

1 个答案:

答案 0 :(得分:0)

我用help of this answer解决了我的问题。这是我用于models.py的修改代码。我的观点只是ModelForm中的标准CreateView。

class Classroom(models.Model):
    ...  dictionary stuff ..
    class_list = models.TextField()
    course_name = models.CharField(max_length=20, choices=COURSE_NAME)
    course_block = models.CharField(max_length=10, choices=BLOCK_NUMBER)
    group_size = models.IntegerField(default=3)

    def __str__(self):
        return self.get_course_block_display()

    def save(self, *args, **kwargs):  
        super(Classroom, self).save(*args, **kwargs)
        # overrides the default save function to parse the class list
        studentList = []
        studentList = self.class_list.split('\n')
        for line in studentList:
            line = line.strip('\r')
            s = Student.objects.create(nickname = line, classroom = self)