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

Python 当一个选项设置为True时,所有其他选项都设置为False(BooleanField),python,django,django-views,Python,Django,Django Views,我有以下表格: 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) 因此,我可以添加一个新选项

我有以下表格:

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

如果您的新选项具有
default=True
,则设置所有现有选项'
default=False
,然后设置您的新选项
default=True
。我不知道你的选项保存后会去哪里。如果您的新选项有
default=true
,请设置所有现有选项'
default=false
,然后设置新选项
default=true
。我不知道你的选项保存后会去哪里。您可能有更好的时间找出哪个选项是正确的,而只是将其设置为错误。

您可以通过自定义模型的
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
    。有第三方软件包允许您这样做,但这可能不值得费心

  • 这个问题和答案没有解决验证问题,如果另一个
    选项model
    已经有
    default=True


您可以通过自定义模型的
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
    。有第三方软件包允许您这样做,但这可能不值得费心

  • 这个问题和答案没有解决验证问题,如果另一个
    选项model
    已经有
    default=True


现在我解决了这个问题,但是使用视图,你知道定制
save()
方法还是在视图中执行更好吗?@M.Gar:对于这样的情况,如果你试图强制执行数据约束,最好将它放在模型中(即
save()
)而不是视图中。首先,可以在视图以外的位置创建对象(管理员、shell等)。另一方面,它使测试更容易。现在我解决了这个问题,但是使用视图,你知道哪个更好,自定义
save()
方法还是在视图中执行?@M.Gar:对于这样的情况,如果你试图强制执行数据约束,最好将它放在模型中(即
save()
),而不是视图中。首先,可以在视图以外的位置创建对象(管理员、shell等)。另一方面,它使测试更容易。