简体   繁体   中英

customizing Django UserCreationForm so that I create the username from lastname and firstname, not the user entering it?

I want to modify my UserCreationForm so that when users request to sign up to my site they get given a username of last_name+'.'+first_name.

my django forms.py:

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User


class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=30, required=False)
    last_name = forms.CharField(max_length=30, required=False)
    email = forms.EmailField(max_length=254)


    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'password1', 'password2', )
        exclude = ['username', ]

So I have excluded the username from the actual form:

<h2>Sign up</h2>
<form method="post">
 {% csrf_token %}
 {% for field in form %}
   <p>
     {{ field.label_tag }}<br>
     {{ field }}
     {% if field.help_text %}
       <small style="color: grey">{{ field.help_text }}</small>
     {% endif %}
     {% for error in field.errors %}
       <p style="color: red">{{ error }}</p>
     {% endfor %}
   </p>
 {% endfor %}
 <button type="submit">Sign up</button>
</form>

and in my views.py:

def signup(request):
    if request.method == 'POST':

        form = SignUpForm(request.POST)

I have tried putting in form.save() here and then trying to get cleaned_data first_name.last_name = username, but it does not work

        if form.is_valid():
            form.save()

            first_name = form.cleaned_data.get('first_name')
            last_name = form.cleaned_data.get('last_name')
            raw_password = form.cleaned_data.get('password1')
            #username = form.cleaned_data.get('username')
            username = firstname+'.'+lastname

            user = authenticate(username=username, password=raw_password)

            user.is_active = False

            user.save()
            return render(request, 'registration/signedup.html', {'user': user})

        else:
            return render(request, 'registration/signup.html', {'form': form, 'invalid': 'Please try again.'})

    else:
        form = SignUpForm()
        return render(request, 'registration/signup.html', {'form': form})

By default the UserCreationForm on init checks if the User model USERNAME_FIELD attribute exists in the forms fields so you don't want to exclude the username attribute unless you've selected another field to be your USERNAME_FIELD .

If you want to use username as the USERNAME_FIELD but you don't want it shown on the front end, you can set it as hidden in your html using the template syntax like {{ form.username.as_hidden }}

You can then override the save method for the SignUpForm , this will allow you to do any post processing once the form is valid.

You also don't need to add password1 and password2 to the fields because they're inherited.

You should set the first_name and last_name to be required if you plan on setting the username attribute to be the combined value of the 2 otherwise the code i've provided below won't work when users DON'T enter their first_name and last_name.

class SignUpForm(UserCreationForm):
    first_name = forms.CharField(max_length=30, required=False)
    last_name = forms.CharField(max_length=30, required=False)
    email = forms.EmailField(max_length=254)


    class Meta:
        model = User
        fields = ('email', 'username', 'first_name', 'last_name')

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        user.username = '{}.{}'.format(
            self.cleaned_data['last_name'],
            self.cleaned_data['first_name']
        )
        if commit:
            user.save()
        return user

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM