使用Django表单集保存具有唯一属性的多个对象 [英] Save multiple objects with a unique attribute using Django formset

查看:130
本文介绍了使用Django表单集保存具有唯一属性的多个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

TL;DR: How do you save/validate multiple objects with a unique attribute using a formset?

假设我有一个机器具有多个设置(请参见下面的模型)。这些设置在机器内应具有唯一的顺序。这可以通过在设置的类中定义 unique_together 属性来实现。 code>模型:

Let's say I have a Machine which has multiple Settings (see models below). These settings should have a unique ordering within the machine. This can be accomplished by defining a unique_together attribute in the Meta class of the Setting model:

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

但是,我使用的是嵌入式表单集来更新所有设置 s 机器。假设我的表单集中有以下信息:

However, I'm using an inline formset to update all the Settings of a Machine. Assume I have the following info in my formset:


  • 设置1:计算机= 1; order = 1

  • 设置2:计算机= 1; order = 2

如果要在两个 Setting 上切换顺序s:

If I were to switch the order on the two Settings:


  • 设置1:机器= 1; order = 2

  • 设置2:机器= 1; order = 1

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

and save the form using the following piece of code:

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

然后我得到了唯一约束错误,因为我正在尝试保存设置1与order = 2,但设置2仍然具有该顺序。我似乎找不到解决此问题的解决方案。我想保留 unique_together 约束以确保数据的正确性。我知道如何使用Javascript在前端解决此问题,但我想检查一下我的模型/表格。遍历表单集行似乎是可能的,但是很丑吗?

Then I get a Unique Constraint Error since I'm trying to save Setting 1 with order=2, but Setting 2 still has that order. I can't seem to find a clean solution for this problem. I would like to keep the unique_together constraint to ensure the correctness of my data. I know how to solve this in the frontend using Javascript, but I want a check in my models/forms. Looping over the formset rows seems possible, but ugly?

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()


推荐答案

似乎无法在数据库级别上限制顺序。我并不是说这是不可能的,但我不知道怎么做。

It seems not possible to constraint the order on the database level. I'm not saying it's not possible, but I don't know how.

现在,我在表单集中添加了一张支票。如果有人遇到类似问题,我将其留在这里。

For now, I added a check in my formset. I'll leave it here in case someone has a similar problem.

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)

这篇关于使用Django表单集保存具有唯一属性的多个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆