吐槽 SegmentFault
本来我是打算写“A Handy Guide for Newbie of Overriding django-allauth Forms and django-rest-auth Serializers”两个一起的。。但是因为SF只允许标题最多64个有效字符,所以我只能分开写了。。
Configurations
You can find all the necessary configurations in the documentation, the only thing I would to highlight is how to customize your login username. Of course, the configurations for overriding the forms will be discussed later.
ACCOUNT_AUTHENTICATION_METHOD = 'username'
ACCOUNT_USERNAME_REQUIRED = True
ACCOUNT_USER_MODEL_USERNAME_FIELD = 'Some_Field'
Once you set the ACCOUNT_USER_MODEL_USERNAME_FIELD
, the username field will be replace be the field you give, Some_Field here for example. However, if this field is not any of the default field, you will need to customize the User model. I will explain how to customize the User model in the end, or there are lots of topics regarding on that which you could find in the internet.
After setting that, you will be able to login using both the username and the field you set. And, all the place where the username is used organically will be replaced by the Some_Field.
Here are the settings for overriding the login and signup form.
ACCOUNT_FORMS = {'login': 'myapp.forms.MyLoginForm'}
ACCOUNT_SIGNUP_FORM_CLASS = 'myapp.forms.MySignupForm'
Overriding Form
#myapp/forms.py
from allauth.account.forms import LoginForm
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field, Fieldset, ButtonHolder, Submit
from crispy_forms.bootstrap import FormActions
class MyLoginForm(LoginForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(LoginForm, self).__init__(*args, **kwargs)
self.fields['password'].widget = forms.PasswordInput()
self.fields["some-field"] = forms.CharField(label='Some label', max_length=100)
# You don't want the `remember` field?
if 'remember' in self.fields.keys():
del self.fields['remember']
helper = FormHelper()
helper.form_show_labels = False
helper.layout = Layout(
Field('login', placeholder = 'Email address'),
Field('password', placeholder = 'Password'),
FormActions(
Submit('submit', 'Log me in to myapp', css_class = 'btn-primary')
),
)
self.helper = helper
class MySignupForm(forms.Form):
first_name = forms.CharField(max_length=30, label='FirstName')
last_name = forms.CharField(max_length=30, label='LastName')
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
Only two things to take note.
- For login form.
You need to addself.request = kwargs.pop('request', None)
beforesuper(LoginForm, self).__init__(*args, **kwargs)
. - For signup from.
Just remember to save the user usinguser.save()
.
Custom User Model
#myapp/model.py
from django.contrib.auth.models import AbstractUser
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
@python_2_unicode_compatible
class User(AbstractUser):
id = models.AutoField(db_column='CompanyId', primary_key=True)
UEN = models.CharField(db_column='UEN', max_length=10, unique=True, help_text='This field is non-editable. Please ensure the number is correct.')
company_name = models.CharField(db_column='Company_Name', max_length=63)
company_address_1 = models.CharField(db_column='Company_Address1', max_length=63)
company_address_2 = models.CharField(db_column='Company_Address2', max_length=63, blank=True)
company_contact_number = models.CharField(db_column='Company_Contact_Number', max_length=31)
company_fax = models.CharField(db_column='Company_Fax', max_length=31)
# company_rep_name = models.CharField(db_column='username')
# company_rep_email_1 = models.CharField(db_column='email')
company_rep_email_2 = models.CharField(db_column='email2', max_length=63, blank=True)
country = models.CharField(db_column='Country', max_length=63, default='Singapore')
postal_code = models.CharField(db_column='Postal_Code', max_length=15)
def __str__(self):
return self.username
def get_absolute_url(self):
return reverse('users:detail', kwargs={'username': self.username})