I’m a big fan of using crispy forms with Django. In fact, since doing the Django girls tutorial, I don’t think I’ve made a form manually.
And, until now, I haven’t been super critical of aesthetics. Now, however, I’m updating the look of the worksheet generator and moved the login to a modal. Doing that, I thought… “Hmm, wouldn’t it be nice if the ‘reset password’ button was in a button group with the login button?”
It turned out to be a bit of a challenge for me, and I couldn’t find anything on it specifically, so here’s what I did:


Functionally, it’s not a big deal, except that I’m using button groups more and more in the site in general, and why not use one here?
However, the old way I was rendering the form wouldn’t work. The crispy FormHelper object rendered the form so completely that I couldn’t get at the login button, much less wrap it together in in a button group.
Of course it was possible, but the solution turned out being telling crispy forms to let me create my own form tag:
# forms.py class LoginForm(forms.Form): username = forms.CharField(label='Username:', max_length=100) password = forms.CharField(label='Password:', widget=forms.PasswordInput(), max_length=100) def __init__(self, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_tag = False
The self.helper.form_tag = False bit turns off the form field.
Then, in the template rendering the form, I had to make some changes. To be honest, I should say that I took the easy way by having crispy forms render the form tag, and then copied that.

Initially, I did this without adding type=”button” to the second button in the group and, for reasons I don’t understand, both buttons functioned at a submit button. Obviously, that wasn’t ideal, and adding the extra type=”button” made it work.
It’s worth pointing out that I never (or, not yet) removed the old …/login.html page that rendered the form before. Nothing links to it, so I doubt anyone will ever hit it. But, if they did, the form would be broken because I didn’t update that template to include a form tag.