使用 Django 表单集保存具有唯一属性的多个对象

2024-04-25

TL;DR:如何使用表单集保存/验证具有唯一属性的多个对象?

假设我有一个Machine其中有多个Settings(参见下面的型号)。这些设置在机器内应具有唯一的顺序。这可以通过定义一个来完成unique_together属性中的Meta的类别Setting model:

unique_together = (('order', 'machine'), )

但是,我使用内联表单集来更新所有Settings of a Machine。假设我的表单集中有以下信息:

  • 设置1:机器=1;订单=1
  • 设置2:机器=1;订单=2

如果我要调换两者的顺序Settings:

  • 设置1:机器=1;订单=2
  • 设置2:机器=1;订单=1

并使用以下代码保存表单:

self.object = machine_form.save()
settings = setting_formset.save(commit=False)
for setting in settings:
    setting.machine = self.object
    setting.save()

然后我收到一个唯一约束错误,因为我尝试使用 order=2 保存设置 1,但设置 2 仍然具有该顺序。我似乎无法找到解决这个问题的干净解决方案。我想保留unique_together约束以确保我的数据的正确性。我知道如何使用 Javascript 在前端解决这个问题,但我想检查我的模型/表单。循环遍历表单集行似乎是可能的,但是很难看?

class Machine(models.Model):
    name = models.CharField(max_length=255)

class Setting(models.Model):
    name = models.CharField(max_length=255)
    machine = models.ForeignKey(Machine, on_delete=models.CASCADE)
    order = models.PositiveSmallIntegerField()

似乎不可能在数据库级别限制顺序。我并不是说这是不可能的,但我不知道如何做到。

现在,我在表单集中添加了一个检查。如果有人遇到类似的问题,我会将其留在这里。

class BaseSettingFormSet(BaseInlineFormSet):
    '''FormSet to update the order of Settings in a Machine'''

    def clean(self):
        '''Checks if there are no two Settings with the same order.'''
        if any(self.errors):
            return
        orders = []
        for form in self.forms:
            if form.cleaned_data:
                order = form.cleaned_data['order']
                if order in orders:
                    form.add_error('order', _('The order of each setting must be unique'))
                else:
                    orders.append(order)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Django 表单集保存具有唯一属性的多个对象 的相关文章

随机推荐