I need advice on how to implement a checkbox in Django

拟墨画扇 提交于 2019-12-14 02:32:22

问题


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">&laquo; 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 &raquo;</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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!