使用查询集为Django中的IntegerField上的选择窗口小部件生成选项

时间:2018-10-22 21:12:26

标签: django django-forms

我正在尝试创建一个站点,用户可以在其中拥有多个头像,并选择进入房间时要使用的头像。 (这将是一个掷骰子的应用程序。)我被困了三天,试图弄清楚如何将查询集传递到表单中,以用作IntegerField上选择小部件的选项。现在,我想我已经成功地将信息传递到了表单中,但是小部件中没有呈现任何内容。 (我什至在表格中也有一份印刷声明,以向我证明信息已经进入。)

model.py

class EnterSWroom(models.Model):
    room_number = models.IntegerField(blank=False)
    passcode = models.CharField(max_length=100, blank=True, null=True)
    default_avatar = models.IntegerField(default=0)

forms.py

class Enter_SW_Room(forms.ModelForm):
    class Meta:
        model = EnterSWroom
        widgets = {'default_avatar': forms.Select(choices=[])}
        fields = ('room_number', 'passcode', 'default_avatar')

    def __init__(self, *args, **kwargs):
        imported_list = kwargs.pop('avatar_list')
        super().__init__(*args, **kwargs)
        self.fields['default_avatar'].choices = imported_list
        print(self.fields['default_avatar'].choices)  #this is just for debugging; see example below

views.py

class DockingBay(FormMixin, TemplateView):
    form_class = Enter_SW_Room

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        # get tuples for avatar choices
        # get user first name (if exists), else use username
        if self.request.user.userprofile.user_first_name:
            user_name = self.request.user.userprofile.user_first_name
        else:
            user_name = self.request.user.username
        # instantiate avatars list, start with user name
        my_avatars = Avatar.objects.filter(user_id=self.request.user.id)
        my_avatars_choices = [(0, user_name)]
        for avatar in my_avatars:
            if avatar.deleted != 1:
                my_avatars_choices.append((avatar.id, avatar.avatar_name))
        kwargs['avatar_list'] = my_avatars_choices
        return kwargs

    def get(self, request, *args, **kwargs):
        kwargs = self.get_form_kwargs()
        # cut for brevity
        form = Enter_SW_Room(**kwargs)
        args = {'form': form, # other args that were cut from this example}

        return render(request, self.template_name, args)
...

打印示例:[(0, 'Eric')] 但是,即使打印显示我已成功将查询集获取到表单,选择小部件也不会显示任何内容。

谢谢!

编辑以添加html模板的片段:

<form method="post">
    {% csrf_token %}
    <table>
        <col width="240">
        <col width="120">
        <tr>
            <td><strong>Room ID:</strong>
            <br>This will be a number.</td>
            <td>{{form.room_number}} <br>
                <strong>{{ form.room_number.errors }}</strong>
            </td>
        </tr>
        <tr>
            <td><strong>Passcode:</strong>
            <br>If the room is open, or you've been in it before, leave this  blank.</td>
            <td>{{form.passcode}} <br>
                <strong>{{ form.passcode.errors }}</strong>
            </td>
        </tr>
        <tr>
            <td><strong>Avatar:</strong>
            <br>Select your avatar.</td>
            <td>{{form.default_avatar}} <br>
                <strong>{{ form.default_avatar.errors }}</strong>
            </td>
        </tr>
    </table>
    <button type="submit">Enter Room</button>
</form>

2 个答案:

答案 0 :(得分:0)

您可以像这样直接在表单初始化中设置选择字段,并由当前用户进行过滤。

class Enter_SW_Room(forms.ModelForm):

    def __init__(self, user, *args, **kwargs):
        super(Enter_SW_Room, self).__init__(*args, **kwargs)
        self.fields['default_avatar'] = forms.ModelChoiceField(
           queryset=Avatar.objects.filter(user=user).exclude(deleted=1)
    )

class Meta:
    model = EnterSWroom
    ......

初始化表单时,请通过用户。

form = Enter_SW_Room(self.request.user)

答案 1 :(得分:0)

哦,我是个白痴。忘记定义表单中的字段。

已添加:

<button class="btn-primary" type="submit">Add to bag</button>

到表格。现在可以了。啊!