Change boolean value in Django ModelForm
Question
I have field in my Model which indicates whether a user wants to receive emails
receive_invites = models.BooleanField(default=True, help_text="Receive an invite email from friends")
I also have a view with an option:
[ x ] I do not want to receive emails...
By default receive_invites is True therefore the checkbox is ticked. However, I'd like the user to tick the checkbox in order to change receive_invites to False. I did the following in my ModelForm to achieve this. Does anybody have a more elegant way of doing this?
class UnsubscribeForm(forms.ModelForm):
class Meta:
model = Entrant
fields = ('receive_invites')
def __init__(self, *args, **kwargs):
if kwargs.has_key('instance'):
instance = kwargs['instance']
if instance.receive_invites:
instance.receive_invites = False
else:
instance.receive_invites = True
super(UnsubscribeForm, self).__init__(*args, **kwargs)
and in the view I have this:
if request.method == 'POST':
unsubscribe_form = UnsubscribeForm(request.POST, instance=me)
if unsubscribe_form.is_valid():
receive_invites = unsubscribe_form.cleaned_data['receive_invites']
if receive_invites:
user.receive_invites = False
else:
user.receive_invites = True
unsubscribe_form.save()
return redirect('index')
else:
unsubscribe_form = UnsubscribeForm(instance=me)
Solution
Adding on to @DrTyrsa, it's unreasonable to go through so much convolution just to follow a field naming convention. If you're attached to that field name, you can always add a property to the model that maps the data field to a value you care about:
dont_receive_invites = models.BooleanField(default=False, help_text="Don't receive an invite email from friends")
@property
def receive_invites(self):
return not self.dont_receive_invites
OTHER TIPS
You can't alter the model? If you can, create dont_receive_invites
field instead and save a lot of time.
Why not just remove the words "do not" from the view?
[ x ] I want to receive emails...
Otherwise, I'd recommend changing UnsubscribeForm
from a ModelForm
to a plain Form
. Then you can invert booleans all you want without resorting to trickery. It's more work, but it'll work if you can't just change the label.