Thoughts on creating CustomUser model with optional account


#1

So I have a project that requires a CustomUser model.

Normally, users would signup for an account before they can create an order. By using the django-allauth package, this can be done quite easily.

I now have a challenge, not only can users create their own account by signing up, users flagged as “is_employee” should be able to create a new user and corresponding order without the need of signing up a user or fill in an emailaddress.

My thoughts on this:

  • We could create a 2nd user model separate from the one being used for signup (not desirable since you would have two models with “first_name”, “last_name” etc.)
  • We could create a “CustomAccount” instead of “CustomUser” and assign a OneToOne relation to “CustomUser” model.

So the CustomAccount would be used when users sign up and create an order, the personal date like “first_name” and “last_name” will be removed from the model and added into the “CustomUser” model. We can use a receiver to update “CustomUser” at the same time we create a “CustomAccount”.

Users flagged as “is_employee” would now be able to create a new user in “CustomUser” model without the requirement of filling in an emailadress or password.

Does this sound feasible or are there other preferable methods?

With best regards,

Kevin


(Vitor Freitas) #2

Hey Kevin!

I think it depends on how you plan to use the data later on. I have used a similar implementation in a project some time ago

The User model would simply handle the authentication with email/password, and I had a Person model with a very complete set of fields including name, etc. There were some Person that had an account to log in, others didn’t have any account at all (because they would never have access to the platform).

But there is also no harm in having some fields in the Order model for “guest account”… Something like:

class Order(models.Model):
    # ... model fields
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    guest_first_name = models.CharField(blank=True)
    guest_last_name = models.CharField(blank=True)
    guest_email = models.CharField(blank=True)

Then in your user interface you can let the employee either associate the Order to one User or just fill the details direct in the other

Maybe it’s worth checking how django-oscar handle this kind of cases, they might have faced this kind of code design decision


#3

Vitor,

Thank you for the reply, I have indeed looked through the code from django-oscar, what they seem to be doing is set the “is_active” flag on the default user model to “False”. Thereby they make sure the guest can not log in or request a password.

On the other hand, they remove the ‘e-mail’ unique constraint to prevent locking out guests who want to order a second time with the same e-mail address. They then block the message django gives from the settings.py regarding the ability to handle non-unique username constraints.

I currently copy the email address to the username field and add a suffix (1,2 or 3) when the same e-mail is being used multiple times. This way the username keeps the unique constraint while being able to use the same email address more than once.

It would be even better if we could handle the e-mailaddress multiple times and use a “is_guest” flag on orders with the same e-mailaddress, then we could convert a guest user into a regular user lateron.