Search code examples
djangodjango-registration

Populate first_name and last_name from full_name


When a user registers in my app, he must enter a full_name. The UserModel has no full_name field, but first_name and last_name, so I have a naive function which is good enough for my use case:

def split_full_name(full_name):
    if not full_name:
        first_name, last_name = None, None
    else:
        parts = full_name.split(' ')
        if len(parts) == 1:
            first_name = parts[0]
            last_name = None
        elif len(parts) == 2:
            first_name = parts[0]
            last_name = parts[1]
        else:
            first_name = parts[0]
            last_name = ' '.join(parts[1:])
    return first_name, last_name

I am overriding the registration form as explained here:

class MyRegistrationForm(RegistrationForm):

    full_name = forms.CharField(required=False)

    def clean_full_name(self):
        full_name = self.cleaned_data['full_name']
        first_name, last_name = split_full_name(full_name)
        self.cleaned_data['first_name'] = first_name
        self.cleaned_data['last_name'] = last_name
        return full_name

But the first_name and last_name from the cleaned_data are not saved to the model. What should I do to achieve that?

I have seen the use of hidden fields for that, but I would like something a bit less hacky. Can I manually populate some fields of the user instance during form validation / processing?

EDIT

Just to avoid confussion: I do not want to add a full_name field to the UserModel. I am just using the stock UserModel, but I want to simplify the form by allowing the user to enter full_name directly and then programatically generating first_name and last_name.


Solution

  • Try setting the first name and last name on the form's instance, instead of adding them to cleaned_data.

    def clean_full_name(self):
        full_name = self.cleaned_data['full_name']
        first_name, last_name = split_full_name(full_name)
        self.instance.first_name = first_name
        self.instance.last_name = last_name
        return full_name
    

    If that doesn't work, I would try overriding the form's save() method and set the values there.

    As an aside, you might have issues assigning None to first_name and last_name. I would use the empty string '' instead.