当一个选项设置为True时,所有其他选项都设置为False(BooleanField)



我有这样的表格:

forms.py
class OptionForm(forms.Form):
    name = forms.CharField(widget=forms.TextInput(attrs={'class' : 'form-control'}), max_length=100, label='Option Name')
    default = forms.BooleanField(label='Default', required=False)

所以我可以添加一个新的选项或编辑一个已经存在的两个视图

views.py
def new_opt(request):
    if request.method=='POST':
        fnewopt = OptionForm(request.POST)
        if fnewopt.is_valid():
            model = OptionModel()
            model.name = fnewopt.cleaned_data.get('name')
            model.default = fnewopt.cleaned_data.get('default')
            model.save()
def edit_opt(request, id_opt):
    opt = OptionModel.objects.get(id=id_opt)
    if request.method == 'POST':
        feditopt = OptionForm(request.POST)
        if feditopt.is_valid():
            model = opt
            model.name = feditopt.cleaned_data.get('name')
            model.default = feditopt.cleaned_data.get('default')
            modelo.save()

但我需要当用户选择一个选项作为默认选项时,无论是新选项还是已经存在的选项,所有其他选项都将默认设置为False

您可以通过自定义模型的save()方法来实现这一点:

def save(self, *args, **kwargs):
    super().save(*args, **kwargs)
    if self.default:
        # At this point self.pk will exist whether
        # this was a new or updated instance.
        # Using update() allows this to run in a single query
        # (plus the query for super().save(), of course).
        OptionModel.objects.exclude(pk=self.pk).update(default=False)

其他一些注意事项:

  • 您应该将save()方法封装在一个原子事务中。

  • 这将在每次保存选项时执行额外的update(),而不仅仅是第一次。为了避免这种情况,您必须检测值何时更改为True。有第三方软件包可以让你做到这一点,但这可能不值得麻烦。

  • 这个问答并没有解决验证问题——如果另一个OptionModel已经有default=True怎么办?

如果您的新选项具有default=True,请设置所有现有选项的default=false,然后设置新选项default = true。我不确定当你的选择被保存时会去哪里。你可能会更好地找出哪个选项是真的,然后设置为假。

最新更新