A Handy Guide for Newbie of Overriding django-allauth Forms

吐槽 SegmentFault

原本我是打算寫「A Handy Guide for Newbie of Overriding django-allauth Forms and django-rest-auth Serializers」兩個一塊兒的。。可是由於SF只容許標題最多64個有效字符,因此我只能分開寫了。。css

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.python

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.django

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.bootstrap

Here are the settings for overriding the login and signup form.segmentfault

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.app

  1. For login form.
    You need to add self.request = kwargs.pop('request', None) before super(LoginForm, self).__init__(*args, **kwargs).
  2. For signup from.
    Just remember to save the user using user.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})

Here is how to override rest-auth serializers

相關文章
相關標籤/搜索