Динамические выпадающие значения django
Я хочу создать выпадающий список Course
"Стажер", в котором будут отображаться только варианты значений в CourseName
"Модель курса". В настоящее время я попробовал некоторые решения после просмотра. Но это не работает. Мой выпадающий список курсов исчез после редактирования в forms.py. Если я удалю эту строку
Course = forms.ChoiceField(widget=forms.Select(attrs={'class':'col-sm-4'}), choices=course_obj.get_course_name(), label='Course :')
Тогда выпадающий список отображается, но без вариантов
model.py
class Course(models.Model):
CourseID = models.AutoField(primary_key=True)
CourseName = models.CharField(max_length=20)
class Meta():
db_table = "Courses"
def get_course_name(self):
return self.CourseName
class Trainee(models.Model):
Name = models.CharField(max_length=50)
Course = models.CharField(max_length=40)
class Meta():
db_table = "Trainee"
forms.py
class TraineeForm(forms.ModelForm):
course_obj = Course()
Name = forms.CharField(widget=forms.TextInput(attrs={'class':'col-sm-4'}), label='Name :')
Course = forms.ChoiceField(widget=forms.Select(attrs={'class':'col-sm-4'}), choices=course_obj.get_course_name(), label='Course :')
........................
edit.html
<form method="post" class="form-group" type="multipart/form-data">
{%csrf_token%}
{% for Name in form.Name %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{{ form.Name.label }}</label>
{{ Name }}
</div>
{% endfor %}
{% for Course in form.Course %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{{ form.Course.label }}</label>
{{ form.Course }}
</div>
{% endfor %}
Страница выглядит следующим образом
===== form.py =====
class TraineeForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(TraineeForm, self).__init__(*args, **kwargs)
self.fields['Course'].widget = forms.Select(choices=Course.objects.values_list('CourseName','CourseName'))
class Meta:
model = Trainee
fields = "__all__"
========= выход ===========
При циклической обработке объекта BoundField - for Name in form.Name
и for Course in form.Course
в вашем случае, Django перебирает его подвиджеты. CharField имеет один суб-виджет, который является самим собой. ChoiceField имеет столько подвиджетов, сколько у него опций, что в вашем случае равно нулю. Вот почему ваша страница отображается таким образом.
Согласно Django's Doc на choices
атрибут ChoiceField
:
Либо итерабель двух кортежей для использования в качестве вариантов для этого поля, либо перечислительные варианты, либо вызываемый объект, возвращающий такую итерабель. Этот аргумент принимает те же форматы, что и аргумент choices для поля модели. Подробнее см. справочную документацию по выбору для поля модели. Если аргумент является вызываемой переменной, он оценивается каждый раз при инициализации формы поля, а также во время рендеринга. По умолчанию используется пустой список.
Попробовать
# forms.py
def course_choices():
return [(course.CourseName, course.CourseName) for course in Course.objects.all()]
class TraineeForm(forms.ModelForm):
Name = forms.CharField(widget=forms.TextInput(attrs={'class':'col-sm-4'}), label='Name :')
Course = forms.ChoiceField(widget=forms.Select(attrs={'class':'col-sm-4'}), choices=course_choices, label='Course :')
class Meta:
model = Trainee
fields = ['Name', 'Course']
А затем в вашем шаблоне:
<!-- edit.html -->
<form method="post" class="form-group" type="multipart/form-data">
{% csrf_token %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{{ form.Name.label }}</label>
{{ Name }}
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{{ form.Course.label }}</label>
{{ form.Course }}
</div>
</form>