Django形式:如何在ManyToMany字段中获取数据?

时间:2020-04-27 13:53:51

标签: python django forms many-to-many

我的目标是实现与管理面板中具有多对多关系的相同功能。一切似乎都可以正常工作,但是当我提交表单时,我得到一些奇怪的结果:我可能遗漏了一些东西,但是我无法弄清楚出了什么问题。

现在,当我添加行时,一切正常。当我尝试从组中删除行时会出现问题。 我正在介绍用户,我有一个“所有用户”的第一个列表,第二个将组成一个组。 当我有一个用户,然后删除另一个用户时,该表单无法通过验证;列表为空,则删除的用户“消失”(不在组列表中,也不在“所有用户”中)。 如果我删除一个用户,然后添加一个新用户,则验证后表单中的唯一用户就是我添加的用户,所有其他用户都将被删除。

我希望我很清楚,在此先感谢您的建议。

这是相关的代码块。

型号:

class UserComp(models.Model):
    """
    Link between users and companies
    Used to restrict display to companie(s) the users belong to
    """
    user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name="Utilisateur")
    company = models.ForeignKey(Company, on_delete=models.CASCADE, verbose_name="Société")
    phone_regex = RegexValidator(regex=r'^0[0-9]([ .-]?[0-9]{2}){4}$', message=("Format de numéro de téléphone invalide"))
    phone_num = models.CharField("numéro de téléphone", validators=[phone_regex], max_length=14, null=True, blank=True)
    is_admin = models.BooleanField("administrateur", default=False)

class EventGroup(models.Model):
    """
    Groups of users
    The link with events is supported by the Event
    (as groups can be reused in several Events)
    """
    company = models.ForeignKey(
        Company, on_delete=models.CASCADE, verbose_name="société"
    )
    users = models.ManyToManyField(UserComp, verbose_name="utilisateurs", blank=True)
    group_name = models.CharField("nom", max_length=100)
    weight = models.IntegerField("poids", default=0)

表格:

class GroupDetail(forms.ModelForm):
    users = forms.ModelMultipleChoiceField(
        label="Dans le groupe",
        queryset=None,
        widget=forms.SelectMultiple,
        required=False
        )
    all_users = forms.ModelMultipleChoiceField(
        label="Utilisateurs",
        queryset=None,
        widget=forms.SelectMultiple,
        required=False
        )

    class Meta:
        model = EventGroup
        fields = ['group_name', 'weight', 'all_users', 'users']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        instance = kwargs.get('instance', None)
        if instance is not None:
            # Users to be selected : all users except the ones already in group
            self.fields['all_users'].queryset= UserComp.objects.\
                                                        filter(company=instance.company).\
                                                        exclude(eventgroup=instance).\
                                                        order_by('user__last_name', 'user__first_name')
            # Current users in group
            self.fields['users'].queryset = instance.users.all().\
                                                     order_by('user__last_name', 'user__first_name')

视图:

def GroupInfo(request, pk):
    current_group = EventGroup.objects.get(id=pk)
    group_form = GroupDetail(request.POST or None, instance=current_group)

    if request.method == 'POST':
        # Values are string and need to be converted to integers to match IDs
        usr_list = [int(elt) for elt in request.POST.getlist('users')]
        group_form.fields['users'].queryset = UserComp.objects.filter(id__in=usr_list)
        if group_form.is_valid():
            new_group.save()
        else:
            # For testing purposes
            print(group_form.errors)

    return render(request, "polls/group_info.html", locals())

要从一个列表中移动用户(实际上是选择多个HTML对象),我使用了这种js代码(一种功能,在双击时称为一次或在循环内调用,移动选定的项(一项或多项),或移动所有项目):

let new_option = new Option($(this).text(), $(this).val())
$('#id_dest').append(new_option);
$(this).remove();

编辑 我做了一些更改,我的问题肯定是要从组中删除用户。 我更新了视图以构建组中的新用户列表(当前用户+要添加的用户-要删除的用户),并添加一个循环以添加每个用户:

def GroupInfo(request, pk):
    current_group = EventGroup.objects.get(id=pk)
    list_users = [elt.id for elt in current_group.users.all()]
    group_form = GroupDetail(request.POST or None, instance=current_group)

    if request.method == 'POST':
        usr_list = [elt.id for elt in current_group.users.all() if elt not in request.POST.getlist('all_users')]
        usr_list += [int(elt) for elt in request.POST.getlist('users')]
        group_form.fields['users'].queryset = UserComp.objects.filter(id__in=usr_list)

        if group_form.is_valid():
            new_group = group_form.save()
            for usr in usr_list:
                new_group.users.add(usr)
            new_group.save()
        else:
            print(group_form.errors)

    return render(request, "polls/group_info.html", locals())

在正面,我进行了2个测试: 1.在提交之前,选择“组”部分中的所有行:我应该检索组中用户的详尽列表,并从该列表中进行构建 2.仅选择更改,在“组”列表中选择新用户,在“ all_users”列表中删除用户。 以某种方式,当我从组中删除用户时,该用户不会传输,并且仍在组中。

0 个答案:

没有答案