如何将ManyToManyField中的数据放入MultipleChoiceField中的选项

时间:2017-01-18 13:19:27

标签: django forms python-3.x models manytomanyfield

我有一张表格:

*# dialogues.forms*

class CreateConferenceForm(forms.Form):
    ...
    participants = forms.MultipleChoiceField(choices=?)
    ...

我需要选择参数而不是“?”来自此模型中的朋友字段的数据:

*# persons.models*

class Person(User):
    ...
    friends = models.ManyToManyField(
        'self',
        related_name='+',
    ) 
    ...

我该怎么做?

2 个答案:

答案 0 :(得分:1)

如果您要使用表单创建会议模型的实例,则应考虑使用Django's ModelForm,它旨在用于创建和编辑模型实例。

在任何一种情况下,您都可以使用ModelMultipleChoiceField来实现您的目的,这只是一个由MultipleChoiceField支持的查询集供其选择。您可以在标准FormModelForm中使用此字段。

要根据请求自定义选项,您可以在视图中设置查询集。

例如:

forms.py

class CreateConferenceForm(forms.Form):
    # An initial queryset is required, this is overwritten in the view
    participants = forms.ModelMultipleChoiceField(Person.objects.all())

views.py

def new_conference(request):
    data = request.POST if request.method == 'POST' else None

    conference_form = CreateConferenceForm(data=data)
    conference_form.fields['participants'].queryset = my_person.friends.all()

    if data:
        if conference_form.is_valid():
            # etc

    return render...

请注意,在表单上调用is_valid之前设置查询集很重要,因为查询集用于验证,并且在将表单传递给模板之前,因为使用了查询集生成显示的选项。

答案 1 :(得分:0)

你可以试试这个

class CreateConferenceForm(forms.Form):
    """
    """
    participants = forms.MultipleChoiceField()

    def __init__(self, *args, **kwargs):
        # Pass the request in the form.
        self.request = kwargs.pop('request', None) 

        super(CreateConferenceForm, self).__init__(*args, **kwargs)

        if self.request:
            pass

        # Get the person object according to you need. Whether from request or hard-coded.
        person = Person.objects.filter().first()
        friend_choices = [(dct['id'], dct['id']) for dct in (person.friends.values('id'))]
        self.fields['participants'].choices = friend_choices

由于朋友字段对象也是具有自我的MamyToMany。你也可以尝试这个

class CreateConferenceForm(forms.Form):
    """
    """
    # Replace second 'id' in values_list('id', 'id') with the field in you person model.
    participants = forms.MultipleChoiceField(choices=list(Person.objects.filter().values_list('id', 'id')))