Select 表单中的字段基于同一模型中的查询集

Select field in form based on queryset in the same model

我想在我的 coach_id 字段的表单中使用查询集的结果填充下拉列表。我只希望用户能够 select 一个选项,而不是多个。我正在尝试使用 ModelMultipleChoiceField...未成功...

class PersonForm(forms.ModelForm):
    coach_id = forms.ModelMultipleChoiceField(queryset=Person.objects.filter(assign_as_coach="Person is a coach"), widget=forms.Select())

    class Meta:
        model = Person
        fields = [ 'id', 'first_name', 'surname', 'email', 'coach_id', 'assign_as_coach', 'position', 'contract_type']
        # exclude = ['initials', 'sam']
        labels = {
            'first_name': _('First Name'),
            'surname': _('Surname'),
            'email': _('Email'),
            'coach_id': _('Select Coach'),
            'assign_as_coach': _('Assign as a coach?'),
            'position': _('Position'),
            'contract_type': _('Contract Type'),
        }

        widgets = {
        'first_name': forms.TextInput(
            attrs={'placeholder': 'First Name', 'id': 'person-first-name'}
        ),
        'surname': forms.TextInput(
            attrs={'placeholder': 'Surname', 'id': 'person-surname'}
        ),
        'email': forms.TextInput(
            attrs={'placeholder': 'Email Address', 'id': 'person-email'}
        ),
        # 'coach_id': forms.Select(
        #   attrs={'placeholder': 'Select Coach', 'id': 'person-coach-id'}
        # ),
        'assign_as_coach': forms.Select(
            attrs={'placeholder': 'Assign person as a coach?', 'id': 'person-is-coach'}
        ),
        'position': forms.TextInput(
            attrs={'placeholder': 'Current position', 'id': 'person-position'}
        ),
        'contract_type': forms.Select(
            attrs={'placeholder': 'Select Contract Type', 'id': 'person-contract'}
        ),

这是我的模型:

class Person(models.Model):

    FT = "Full-Time"
    PT = "Part-Time"
    C = "Contract"
    Z = "Zero hours"

    CONTRACT_CHOICES = (
    (FT, "Full-Time"),
    (PT, "Part-Time"),
    (C, "Contract"),
    (Z, "Zero hours"),
    )

    Y = "Yes"
    N = "No"

    IS_COACH_CHOICES = (
    (Y, "Person is a coach"),
    (N, "Person is NOT a coach"),
    )


    first_name = models.CharField(max_length=15, default='')
    surname = models.CharField(max_length=30, default='')
    initials = models.CharField(max_length=5, default='', null=True, blank=True)
    email = models.EmailField(default='', null=True, blank=True)
    coach_id = models.IntegerField(null=True)
    assign_as_coach = models.CharField(null=True, blank=True, choices=IS_COACH_CHOICES, default="Person is NOT a coach", max_length=5)
    position = models.CharField(max_length=30, default='', null=True, blank=True)
    contract_type = models.CharField(max_length=30, default='FT', choices=CONTRACT_CHOICES)
    user_name_check = models.CharField(max_length=30, default='', null=True, blank=True)
    def __unicode__ (self):
        return self.surname + ', ' + self.first_name

目前,我的模板上有一个 coach_id select 字段渲染,其中没有任何内容且格式错误。

您可以将 coach_id 重命名为 coach(否则您将得到冲突的列名)并使其成为同一模型的外键:coach=models.ForeignKey('self', on_delete=models.CASCADE, null=True)。这将使您的教练字段变成下拉列表。

然后您可以通过在表单的 init 方法中设置字段的 queryset 属性来限制下拉列表的选择:

self.fields['coach'].queryset = Person.objects.filter(assign_as_coach__exact='Y').