Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best method to make additional user fields required? #47

Closed
joshvillbrandt opened this issue Apr 25, 2019 · 4 comments
Closed

Best method to make additional user fields required? #47

joshvillbrandt opened this issue Apr 25, 2019 · 4 comments

Comments

@joshvillbrandt
Copy link

joshvillbrandt commented Apr 25, 2019

Hey there!

What would be the best way to make additional fields required for the user model? For example, it appears that only username and password are required in Django User model, but I would like to have first_name, last_name, and email required via the "accounts/register" endpoint.

One way I could do this would be to set define a custom Django user model, but I think I want first_name and last_name to not be required internally in case I want to make daemon/service accounts.

I think the next best way would be to override the registration serializer via the DefaultRegisterUserSerializer setting. Is this what you would recommend? Could you write a quick example using this method if so?

PS: Thanks for making this library, @apragacz! I'm excited to finish implementing it. It looks like exactly what I need. :)

@apragacz
Copy link
Owner

apragacz commented Apr 26, 2019

Hi @joshvillbrandt

Not sure if I understand your question. Assuming you are using the default User model (this is set by AUTH_USER_MODEL Django setting) the DefaultRegisterUserSerializer will infer that it will require following fields: username, first_name, last_name, email, password, password_confirm, which is illustrated by this testcase:

def test_ok(self):
serializer_class = registration_settings.REGISTER_SERIALIZER_CLASS
serializer = serializer_class(data={})
field_names = {f for f in serializer.get_fields()}
self.assertEqual(
field_names,
{'id', 'username', 'first_name', 'last_name', 'email',
'password', 'password_confirm'},
)

(id is readonly so it's not actually used)

You can limit the fields by adding other fields you want to hide to ‘USER_HIDDEN_FIELDS’ setting. Even better, you can use ‘USER_PUBLIC_FIELDS’ setting to specify which fields exactly you want to have in register endpoint (again DefaultRegisterUserSerializer is inferring these; it will add the password, password_confirm fields automatically even if they are not listed in ‘USER_PUBLIC_FIELDS’ setting).

If on the other hand, you want additional fields in the register endpoint, which cannot be inferred from your user model, the only option I see is to replace DefaultRegisterUserSerializer by using 'REGISTER_SERIALIZER_CLASS'. You can consider subclassing DefaultRegisterUserSerializer as it contains all the validation logic like for instance testing for non-trivial passwords.

Hope this helps in any way. If not, you are more than welcome to clarify!

@joshvillbrandt
Copy link
Author

Hmm. I am a bit confused. When I hit my "accounts/register" endpoint right now, let's say with no data, the response I get is:

{"password":["This field may not be blank."],"username":["This field may not be blank."]}

My desired behavior is that the response also lists first_name, last_name, and email as "This field may not be blank." Are you saying that this should already be the case?

They way that I am interpreting the test_ok test that you embedded is simply that it verifies that the fields are supported by the serializer, but not anything about whether they are required or not.

If it makes a difference, I am only using Django 1.11. Maybe Django changed which fields were required by default. I'll that that out.

@joshvillbrandt joshvillbrandt changed the title Best method of requiring addition user fields? Best method to make additional user fields required? May 3, 2019
@joshvillbrandt
Copy link
Author

Alright, it appears that I was in fact sending first_name, last_name, and email which were not tripping Django's "blank" validation. I suppose the best way to change this would indeed be to set AUTH_USER_MODEL to a custom user model and to have those fields of min_length validators.

For the time being, I'm just having my javascript change empty strings to nulls. It's not server-side validated, but that is okay with me in this scenario.

Thanks for your time, @apragacz!

@lock
Copy link

lock bot commented May 5, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators May 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants