Best approach to handling different types of Users

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Best approach to handling different types of Users

Cameron-40
Hi, I'm wondering if anyone can help shed some light on the best
approach is too creating different Users. I'm trying to make a online
shop, that features two types of Users, "Customers" and "Merchants".
The power of each Users vary greatly, Customers can buy items from
Merchants and Merchants can (as you would expect) list new products,
edit them. Merchants required additional information compared to
Customers (such as Address, Contact Info, Payment details).

Now hows the best way to handle this? I've read that subclassing the
User class is bad (I'm not entirely sure why though). Most examples
try to extend the User class, with a UserProfile class with a OneToOne
relationship to the User class (like this http://pastebin.com/GQVLrVTx).
Is it better to extend that to a UserProfileMerchant and
UserProfileCustomer, or have a single UserProfile, and have a boolean
field to indicate if the account is a Merchant? (both examples in the
following - http://pastebin.com/F8ZenCa1)

Any advice on the matter would be greatly appreciated!

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

dfolland-2
Try using "Groups" that is part of the Django user authentication.

https://docs.djangoproject.com/en/dev/topics/auth/



On Aug 18, 6:56 am, Cameron <[hidden email]> wrote:

> Hi, I'm wondering if anyone can help shed some light on the best
> approach is too creating different Users. I'm trying to make a online
> shop, that features two types of Users, "Customers" and "Merchants".
> The power of each Users vary greatly, Customers can buy items from
> Merchants and Merchants can (as you would expect) list new products,
> edit them. Merchants required additional information compared to
> Customers (such as Address, Contact Info, Payment details).
>
> Now hows the best way to handle this? I've read that subclassing the
> User class is bad (I'm not entirely sure why though). Most examples
> try to extend the User class, with a UserProfile class with a OneToOne
> relationship to the User class (like thishttp://pastebin.com/GQVLrVTx).
> Is it better to extend that to a UserProfileMerchant and
> UserProfileCustomer, or have a single UserProfile, and have a boolean
> field to indicate if the account is a Merchant? (both examples in the
> following -http://pastebin.com/F8ZenCa1)
>
> Any advice on the matter would be greatly appreciated!

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

Andre Terra
In reply to this post by Cameron-40
Do create a UserProfile with an FK to user, but add an FK to Group as well. This way you can take advantage of the existing Permissions application which would allow/deny users access to various parts of your application.

Just make sure your views take those permissions into consideration!


Cheers,
AT

On Thu, Aug 18, 2011 at 8:56 AM, Cameron <[hidden email]> wrote:
Hi, I'm wondering if anyone can help shed some light on the best
approach is too creating different Users. I'm trying to make a online
shop, that features two types of Users, "Customers" and "Merchants".
The power of each Users vary greatly, Customers can buy items from
Merchants and Merchants can (as you would expect) list new products,
edit them. Merchants required additional information compared to
Customers (such as Address, Contact Info, Payment details).

Now hows the best way to handle this? I've read that subclassing the
User class is bad (I'm not entirely sure why though). Most examples
try to extend the User class, with a UserProfile class with a OneToOne
relationship to the User class (like this http://pastebin.com/GQVLrVTx).
Is it better to extend that to a UserProfileMerchant and
UserProfileCustomer, or have a single UserProfile, and have a boolean
field to indicate if the account is a Merchant? (both examples in the
following - http://pastebin.com/F8ZenCa1)

Any advice on the matter would be greatly appreciated!

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

schinckel
In reply to this post by Cameron-40
Lately, I have been looking at using subclasses of auth.User as a way of segmenting users.

This appears (to me, at this stage, anyway) to have several advantages over using the UserProfile approach.

* You can have extra attributes on the subclass. For instance, one set of users belong to a Company, and I can do this FK relation from the subclass. Similarly, I can have a date_of_birth field that is attached to the user, rather than the UserProfile. From a performance perspective, this doesn't make a lick of difference, as a subclass of a concrete class still has a join anyway.
* You can easily have different user classes appear differently in the admin.
* You can have different relationships between particular User types and other objects. For instance, a Staff user may 'work_at' a Location, but an 'AreaManager' may have a 'manages' relationship to an Area. You can still do this with auth.User, but every user will have every relationship.

The biggest helper for this was to have an authentication backend that automatically selects the subclass, so that you no longer get a User object in request.user, but whatever you want.

A drawback is that you can't easily change the field types: email, which I use for authentication, needs to be unique. You can handle this with validation checking on forms, but that requires you to remember to build this into your forms. The other way is to monkey-patch the User class directly, and manually fix the database to not allow duplicates on the email column.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/Y6qCTdPzU9sJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

Andre Terra
Until you install some third party app that accesses
User.objects.all() and then suddenly nothing works as it's supposed
to.

You can access the User object from its related UserProfile instance
and do everything you say from there instead of breaking the
convention. Nobody's stopping you from writing an abstract
BaseUserProfile model with an FK to User and custom UserProfile
subclasses. I just don't see any advantages in going down that path.

Because how will you access every user if you ever need to? What if
someone gets promoted? How will you separate view from model logic?
Are you going to rewrite forms for every user class? That's probably
going to be hard to maintain.


FWIW, profiles are the canonical solution. They are also the only
elegant solution, at least until the app loading branch lands on
trunk, which should then allow you to register a different class as
User. But that won't happen any time soon..


Cheers,
AT

On 8/18/11, Matt Schinckel <[hidden email]> wrote:

> Lately, I have been looking at using subclasses of auth.User as a way of
> segmenting users.
>
> This appears (to me, at this stage, anyway) to have several advantages over
> using the UserProfile approach.
>
> * You can have extra attributes on the subclass. For instance, one set of
> users belong to a Company, and I can do this FK relation from the subclass.
> Similarly, I can have a date_of_birth field that is attached to the user,
> rather than the UserProfile. From a performance perspective, this doesn't
> make a lick of difference, as a subclass of a concrete class still has a
> join anyway.
> * You can easily have different user classes appear differently in the
> admin.
> * You can have different relationships between particular User types and
> other objects. For instance, a Staff user may 'work_at' a Location, but an
> 'AreaManager' may have a 'manages' relationship to an Area. You can still do
> this with auth.User, but every user will have every relationship.
>
> The biggest helper for this was to have an authentication backend that
> automatically selects the subclass, so that you no longer get a User object
> in request.user, but whatever you want.
>
> A drawback is that you can't easily change the field types: email, which I
> use for authentication, needs to be unique. You can handle this with
> validation checking on forms, but that requires you to remember to build
> this into your forms. The other way is to monkey-patch the User class
> directly, and manually fix the database to not allow duplicates on the email
> column.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/django-users/-/Y6qCTdPzU9sJ.
> To post to this group, send email to [hidden email].
> To unsubscribe from this group, send email to
> [hidden email].
> For more options, visit this group at
> http://groups.google.com/group/django-users?hl=en.
>
>

--
Sent from my mobile device

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

schinckel

On Friday, August 19, 2011 12:07:44 PM UTC+9:30, Andre Terra (airstrike) wrote:
Until you install some third party app that accesses
User.objects.all() and then suddenly nothing works as it's supposed
to.

Why wouldn't it? The User subclasses will still appear in the User.objects.all() queryset. 

You can access the User object from its related UserProfile instance
and do everything you say from there instead of breaking the
convention. Nobody's stopping you from writing an abstract
BaseUserProfile model with an FK to User and custom UserProfile
subclasses. I just don't see any advantages in going down that path.

 As I said, 'at this stage', it all seems to be working out okay. I have plenty of 3rd party apps, and even some of my own, that access User, and they still work with sub-classes.

Because how will you access every user if you ever need to? What if
someone gets promoted? How will you separate view from model logic?
Are you going to rewrite forms for every user class? That's probably
going to be hard to maintain.

 You can still access User.objects.all(). I even have a way to access the sub-classes (downcasting) when fetching all users.

FWIW, profiles are the canonical solution. They are also the only
elegant solution, at least until the app loading branch lands on
trunk, which should then allow you to register a different class as
User. But that won't happen any time soon..

See, I don't see them as an elegant solution. Having to do:

    user.get_profile().date_of_birth 

instead of:

    user.date_of_birth

irks me every time I write the code. UserProfile has always felt to me that it was a patchy way of extending User.

Matt.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/-B-vk5gzPqcJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

Andre Terra
Alright, do what you will. Whatever floats your boat..

On Fri, Aug 19, 2011 at 5:12 AM, Matt Schinckel <[hidden email]> wrote:

On Friday, August 19, 2011 12:07:44 PM UTC+9:30, Andre Terra (airstrike) wrote:
Until you install some third party app that accesses
User.objects.all() and then suddenly nothing works as it's supposed
to.

Why wouldn't it? The User subclasses will still appear in the User.objects.all() queryset. 

You can access the User object from its related UserProfile instance
and do everything you say from there instead of breaking the
convention. Nobody's stopping you from writing an abstract
BaseUserProfile model with an FK to User and custom UserProfile
subclasses. I just don't see any advantages in going down that path.

 As I said, 'at this stage', it all seems to be working out okay. I have plenty of 3rd party apps, and even some of my own, that access User, and they still work with sub-classes.

Because how will you access every user if you ever need to? What if
someone gets promoted? How will you separate view from model logic?
Are you going to rewrite forms for every user class? That's probably
going to be hard to maintain.

 You can still access User.objects.all(). I even have a way to access the sub-classes (downcasting) when fetching all users.

FWIW, profiles are the canonical solution. They are also the only
elegant solution, at least until the app loading branch lands on
trunk, which should then allow you to register a different class as
User. But that won't happen any time soon..

See, I don't see them as an elegant solution. Having to do:

    user.get_profile().date_of_birth 

instead of:

    user.date_of_birth

irks me every time I write the code. UserProfile has always felt to me that it was a patchy way of extending User.

Matt.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/-B-vk5gzPqcJ.

To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

DrBloodmoney
On Fri, Aug 19, 2011 at 9:27 AM, Andre Terra <[hidden email]> wrote:

> Alright, do what you will. Whatever floats your boat..
>
> On Fri, Aug 19, 2011 at 5:12 AM, Matt Schinckel <[hidden email]> wrote:
>>
>> On Friday, August 19, 2011 12:07:44 PM UTC+9:30, Andre Terra (airstrike)
>> wrote:
>>>
>>> Until you install some third party app that accesses
>>> User.objects.all() and then suddenly nothing works as it's supposed
>>> to.
>>
>> Why wouldn't it? The User subclasses will still appear in the
>> User.objects.all() queryset.
>>>
>>> You can access the User object from its related UserProfile instance
>>> and do everything you say from there instead of breaking the
>>> convention. Nobody's stopping you from writing an abstract
>>> BaseUserProfile model with an FK to User and custom UserProfile
>>> subclasses. I just don't see any advantages in going down that path.
>>
>>  As I said, 'at this stage', it all seems to be working out okay. I have
>> plenty of 3rd party apps, and even some of my own, that access User, and
>> they still work with sub-classes.
>>>
>>> Because how will you access every user if you ever need to? What if
>>> someone gets promoted? How will you separate view from model logic?
>>> Are you going to rewrite forms for every user class? That's probably
>>> going to be hard to maintain.
>>
>>  You can still access User.objects.all(). I even have a way to access the
>> sub-classes (downcasting) when fetching all users.
>>>
>>> FWIW, profiles are the canonical solution. They are also the only
>>> elegant solution, at least until the app loading branch lands on
>>> trunk, which should then allow you to register a different class as
>>> User. But that won't happen any time soon..
>>
>> See, I don't see them as an elegant solution. Having to do:
>>     user.get_profile().date_of_birth
>> instead of:
>>     user.date_of_birth
>> irks me every time I write the code. UserProfile has always felt to me
>> that it was a patchy way of extending User.
>> Matt.
>>

Not being able to define your own User model is easily my least
favorite thing about django. User.get_profile() is an antipattern.

I hope we get the ability to define our own User model makes it into
contrib.auth at some point (lazy loaded)

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

Malcolm Box
In reply to this post by Andre Terra

On 19 August 2011 03:37, Andre Terra <[hidden email]> wrote:
Until you install some third party app that accesses
User.objects.all() and then suddenly nothing works as it's supposed
to.


I hear this a lot that "things will break" if you subclass User. However, I haven't seen anyone share a concrete example of *how* things go wrong.

Anyone got a good example to scare the children with?

Malcolm

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

Cameron-40

> I hear this a lot that "things will break" if you subclass User. However, I
> haven't seen anyone share a concrete example of *how* things go wrong.
>
> Anyone got a good example to scare the children with?
>
> Malcolm

Yeh, I've heard this quite a bit as well. An example of a scenario
this really catchs you out would be great.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

dfolland-2
In reply to this post by dfolland-2
Like I said use the "Groups" and then like what was suggested
"Permissions".  That should handle what your are trying to do and not
introduce any conflicts.

On Aug 18, 9:17 am, dfolland <[hidden email]> wrote:

> Try using "Groups" that is part of the Django user authentication.
>
> https://docs.djangoproject.com/en/dev/topics/auth/
>
> On Aug 18, 6:56 am, Cameron <[hidden email]> wrote:
>
>
>
>
>
>
>
> > Hi, I'm wondering if anyone can help shed some light on the best
> > approach is too creating different Users. I'm trying to make a online
> > shop, that features two types of Users, "Customers" and "Merchants".
> > The power of each Users vary greatly, Customers can buy items from
> > Merchants and Merchants can (as you would expect) list new products,
> > edit them. Merchants required additional information compared to
> > Customers (such as Address, Contact Info, Payment details).
>
> > Now hows the best way to handle this? I've read that subclassing the
> > User class is bad (I'm not entirely sure why though). Most examples
> > try to extend the User class, with a UserProfile class with a OneToOne
> > relationship to the User class (like thishttp://pastebin.com/GQVLrVTx).
> > Is it better to extend that to a UserProfileMerchant and
> > UserProfileCustomer, or have a single UserProfile, and have a boolean
> > field to indicate if the account is a Merchant? (both examples in the
> > following -http://pastebin.com/F8ZenCa1)
>
> > Any advice on the matter would be greatly appreciated!

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Reply | Threaded
Open this post in threaded view
|

Re: Best approach to handling different types of Users

Joshua Russo-2
In reply to this post by Cameron-40
Things will break in the sense that, if you add another app that accesses the User model they will only see the original implementation. They won't get your subclass. Other than that, other apps that use the User model should "work" just fine.

Unless I'm missing something, and in that case someone can kindly correct me. :o)

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/qeQeHTmp_E8J.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.