Django:ModelForm使用自定义查询预填充复选框

时间:2015-06-20 16:26:50

标签: django django-forms django-queryset modelform

我正在开发我的第一个Django项目。

我在两个模型之间存在多对多关系:用户和项目。 在更新项目时,我想显示带有添加新成员的表单,并根据当前项目用户删除具有正确选择的现有成员字段。

这是我到目前为止所尝试的内容:

  1. 从网址
  2. 获取当前项目
  3. 将当前项目传递给模型表单
  4. 在表单中,运行自定义查询集。
  5. 问题:不显示查询集的结果。

    在views.py

    类UpdateProject(LogInRequiredMixin,UpdateView):

    """ Class to Edit Project.
    """
    
    form_class = ProjectUpdateForm
    template_name = 'project/create.html'
    
    def get_object(self):
        self.project_instance = models.Project.objects.get(pk=self.kwargs['project'])
            return self.project_instance
    
    def get_form_kwargs(self):
        kwargs = super(UpdateProject, self).get_form_kwargs()
        kwargs.update({'project': self.project_instance})
        return kwargs
    

    表格 ProjectUpDateForm

    class ProjectUpdateForm(forms.ModelForm):
        """ Form to update Project Field. """
    
        add_member = forms.CharField(label="Add New Members", widget=forms.CheckboxSelectMultiple)
        del_member = forms.CharField(label="Remove Members", widget=forms.CheckboxSelectMultiple)
    
        def __init__(self, *args, **kwargs):
            self.project = kwargs.pop('project')
            super(ProjectUpdateForm, self).__init__(*args, **kwargs)
            print MyUser.objects.exclude(pk__in=self.project.members.all())
            print MyUser.objects.filter(pk__in=self.project.members.all())
    
            self.fields['add_member'].queryset = MyUser.objects.exclude(pk__in=self.project.members.all())
            self.fields['del_member'].queryset = MyUser.objects.filter(pk__in=self.project.members.all())
    
       # Rest of Class Logic
    

    打印语句正在运行并返回正确的结果,但是我无法在应用中查看结果。它显示为空白。

    另外,我想知道的是他们更容易实现同样的方法吗? (在我看来,我不应该明确地传递项目?)

3 个答案:

答案 0 :(得分:1)

据我所知,这解决了问题

在“模型表单”中明确添加“多对多”字段时,如果您希望多次响应,则使用的模块应为ModelMultipleChoiceField

此外,由于我们正在使用init方法,并且在其中有一个查询集,因此定义它的最佳位置是在init内。

最终表格代码:

{
  "type": "object",
  "additionalProperties": {
    "type": "object",
    "etc": "etc"
  }
}

这应该这样做!

可能对某人有用

如果我们已经在模型中定义了字段,我们不需要在 init 中完全覆盖它(如果查询需要传递参数)

我们可以在init中定义它的queryset self.fields [' field_name']。queryset = logic

在Meta类中添加小部件。

PS:我仍然在寻找更简单的方法来访问当前对象,而不是通过View显式传递!

答案 1 :(得分:1)

我理解添加add_memberdel_member操作的想法。

但是为什么你不能只用一个ModelMultipleChoiceField来显示项目中的每个用户,只需勾选复选框以显示已经参与项目的用户?

我没有对此进行测试,但它可能看起来像:

class ProjectForm(forms.ModelForm):

    class Meta:
        model = Project
        fields = ['title', 'description']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        current_members = self.instance.members.all() # What are the current members?
        possible_members = User.objects.all() # Change this if you want a different set of users to add.
        self.fields['members'] = forms.ModelMultipleChoiceField(label="Members",
                                                                widget=forms.CheckboxSelectMultiple,
                                                                queryset=possible_members,
                                                                initial=current_members,
                                                                required=False) # If it can be empty

    def save(self, commit=True):
        instance = super().save(commit=False)  # Saving with commit=False add a save_m2m method to self
        if commit:
            instance.members.clear()           # We delete every member
            for m in self.cleaned_data.get('members'): # We them add again every checked user as member at form submission
                instance.members.add(m)
            instance.save()                    # We save the instance
            self.save_m2m()                    # We also save the changes in the M2M relationship.
            return instance

诀窍是检索当前是项目实例成员的用户并预先选中复选框以在所有用户的整个列表中显示它们(已选中:用户是成员,未选中的用户:不是成员的用户)。

因此,如果您选中一个框,则添加该用户,如果取消选中该框,则将其从成员列表中删除。

答案 2 :(得分:0)

首页HTML代码:

<td><input type="checkbox" name="checks[]" value="{{ customer.pk }}"></td>

后端views.py代码:

models.Customer.objects.filter(pk__in=request.POST.getlist('checks[]')).update(consultant_id=None)

infact name ='V'== getlist('V'),不需要[]

===========

<td><input type="checkbox" name="checks" value="{{ customer.pk }}"></td>

models.Customer.objects.filter(pk__in = request.POST.getlist(''checks'))