问题
I am trying to create a way that a student can enroll to a teacher's course. I added a boolean field to my StudentData model and from there I added a many-to-many field to my Course model. Each of my course page is a generated slug page and there all students are listed. I want that near each student a checkbox will be shown. And if teacher selects more students and presses Enroll button, only those students can view the course.
Now, the template conditionals I can do them myself, but I am stuck on updating data the right way using the checkbox. This is the boilerplate:
<ul>
{% for student in students %}
<br>
<br>
{{ student.name }} {{ student.surname }}<input type='checkbox' {% ifequal value 0 %}checked{% endifequal %}> 0
<br>
<br>
{% endfor %}
</ul>
<div class="row">
<div class="col-md-4">
<div class="pagination">
<span class="step-links">
{% if students.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ students.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
{{ students.number }}
</span>
{% if students.has_next %}
<a href="?page={{ students.next_page_number }}">next</a>
<a href="?page={{ students.paginator.num_pages }}">last »</a>
{% endif %}
</span>
</div>
</div>
<div class="col-md-4">
<button class="btn-success">Enroll</button>
</div>
</div>
class StudentDataForm(forms.ModelForm):
enrolled = forms.BooleanField()
def __init__(self):
if self.checked:
self.fields['enrolled'].initial = True
class Meta:
model = StudentData
fields = ('enrolled', )
class StudentData(models.Model):
name = models.CharField(max_length=30)
surname = models.CharField(max_length=50)
student_ID = models.CharField(unique=True, max_length=14)
notes = models.CharField(max_length=255, default=None, blank=True)
enrolled = models.BooleanField(default=False)
course = models.ManyToManyField('Course', default=None, blank=True)
class Course(models.Model):
study_programme = models.ForeignKey('StudyProgramme', on_delete=models.CASCADE, default='')
name = models.CharField(max_length=50, unique=True)
ects = models.PositiveSmallIntegerField(validators=[MaxValueValidator(99)])
description = models.TextField()
year = models.PositiveSmallIntegerField(validators=[MaxValueValidator(99)])
semester = models.IntegerField(choices=((1, "1"),
(2, "2"),
), default=None)
teacher1 = models.ForeignKey('TeacherData', on_delete=models.CASCADE, default=None,
verbose_name="Course Teacher", related_name='%(class)s_course_teacher')
teacher2 = models.ForeignKey('TeacherData', on_delete=models.CASCADE, default=None, null=True,
verbose_name="Seminar Teacher", related_name='%(class)s_seminar_teacher')
slug = models.SlugField(max_length=150, unique=True)
回答1:
Why 2 similar questions? Need advice on implementing feature regarding Django models
Personally, it's better to have the ManyToManyField
relating course and students in the Course
model. It's easy because, after this, all you need to do is to load the form and post it. Then:
class Course(models.Model):
# all your fields
students = models.ManyToManyField(StudentData)
class CourseForm(forms.ModelForm):
class Meta:
model = Course
fields = "__all__"
By default, ManyToManyField
in forms is represented by a SelectMultiple
widget. If you prefer checkboxes:
class CourseForm(forms.ModelForm):
class Meta:
model = Course
fields = "__all__"
widgets = {
'students': forms.CheckboxSelectMultiple
}
In your template, just load the form {{form}}
and the teacher would select with checkboxes which students are in the course. Each student will see the course by filtering using reverse ManyToManyField
relationship:
student = Student.objects.get(name='John', surname='Doe')
courses = student.course_set.all() # These are all the courses where the student is enrolled
That's the good point of ManyToManyField
. You can assign students from the CourseForm
and access them from student model using reverse relationship course_set
.
回答2:
You should not specify the field explicitly inthe ModelForm
because it is already defined in the model.
class StudentDataForm(forms.ModelForm):
class Meta:
model = StudentData
fields = ('enrolled', )
That's for the form definition. If you want to pass initial values then instantialize it like
form = StudentDataForm(initial={'enrolled': True})
and it will magically(not so) create the ModelForm instance with initially enrolled
field checked.
Now in template all you have to render this form is (You must pass the form in the template render in context context={'form': form}
)
...
{{ form }}
...
and that will render the form but if you want to render it manually, do it like this
...
{{ form.enrolled }}
...
and it will render only the checkbox. Keep in mind that you must nest it in <form>
tags and add here a submit
button.
more resources:
Model Form | Django docs
Providing initial values | Django docs
来源:https://stackoverflow.com/questions/49003113/i-need-advice-on-how-to-implement-a-checkbox-in-django