Расширение ManyToManyField В Шаблонах

#django #django-models #django-forms #django-templates

Вопрос:

Мне нужно создать множество полей, в которых есть несколько опций, а затем рядом с каждой опцией есть дополнительное поле
Мои модели:

 class Subject(models.Model):
    name = models.CharField(max_length=30)
    duration = models.IntegerField()
    price = models.IntegerField()

class Student(models.Model):
    firstname = models.CharField(max_length=30)
    lastname = models.CharField(max_length=30)
    subject = models.ManyToManyField(Subject,through="StudentSubject")

class StudentSubject(models.Model)
    student = models.ForeignKey(Student,on_delete=models.CASCADE)
    subject = models.ForeignKey(Subject,on_delete=models.CASCADE)
    discount = models.IntegerField()
 

Я использовал промежуточную модель StudentSubject(она содержит дополнительное поле), но я не уверен, как мне следует отображать это в шаблоне, который я хочу сделать примерно так:

 Math DiscountField1
Physics DiscountField2
CompSci DiscountField3
 

Ответ №1:

Вы можете перечислить через StudentSubject so для студента, которого вы можете иметь:

 {% for studentsubject in mystudent.studentsubject_set.all %}
    {{ studentsubject.subject.name }} {{ studentsubject.discount }}
{% endfor %} 

с mystudent , студентом, для которого вы перечисляете предметы с соответствующей скидкой.

Вы можете повысить эффективность, предварительно выбрав и выбрав связанные объекты в представлении, чтобы:

 from django.db.models import Prefetch
from django.shortcuts import render

def my_view(request, pk):
    qs = Student.objects.prefetch_related(
        Prefetch(
            'studentsubject_set',
            queryset=StudentSubject.objects.select_related('subject')
        )
    )
    mystudent = get_object_or_404(qs, pk=pk)
    # …
    return render(request, 'some-template.html', {'mystudent': mystudent}) 

Комментарии:

1. Я на самом деле хочу сделать что-то вроде этого: <форма> {% для предмета в предметах %} <форма><метка>{{тема}}<метка></метка> </метка><тип ввода=»число» имя=»поле скидки» /> {% конец для %} <тип ввода=»число» имя=»поле скидки» /></форма> однако я хочу отобразить поле скидки как поле объекта StudentSubject, а затем найти способ его сохранить. В принципе, я хочу сделать форму, в которой вы можете выбрать тему и добавить скидку

2. Затем вы должны сделать а ModelForm для StudentSubject модели.

3. Я мог бы, но я хочу перечислить каждый предмет, если бы я создал форму модели, я мог бы выбрать только 1 предмет в то время. Моя цель состоит в том, чтобы установить флажок рядом с каждым предметом и добавить их таким образом в модель учащихся

4. @ppcase: нет, вы завернете это ModelForm в a FormSet , а затем вместе с Subject queryset. Кроме того, если скидка предоставляется по каждому предмету: docs.djangoproject.com/en/3.2/topics/forms/formsets

5. вы имеете в виду что-то вроде этого: StudentSubjectFormSet = formset_factory(StudentSubjectForm, extra=len(Субъект.объект.все ()))?

Ответ №2:

Вы можете передать промежуточную модель в контекст:

 context['student_subjects'] = StudentSubject.objects.select_related('subject').all()
 

Затем в шаблоне:

 {% for s in student_subjects %}
    {{ s.subject.name }} {{ s.discount }}
{% endfor %}
 

Комментарии:

1. кажется, я не очень хорошо объясняю,что я хочу делать, по сути, я хочу перечислить все предметы, например, математику, физику и т.д., А затем рядом с каждым добавить целое поле, которое является скидкой, поэтому каждый раз, когда форма отправляется, она создает модель объекта для студентов, которая будет иметь эту скидку