Динамические выпадающие значения 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 %}

Страница выглядит следующим образом enter image description here

===== 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__"

========= выход ===========

enter image description here

При циклической обработке объекта 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>
Вернуться на верх