On Mon, Aug 10, 2015 at 12:11 PM, Ankit Agrawal <aaaagra...@gmail.com>
wrote:

> Hi James,
>
>      Correct me if I am wrong but if I understood you correctly, I should
> be able to implement it this way -
>
> class User(AbstractBaseUser, PermissionsMixin):
>     common_fields_go_her = ...
>
>     objects = CustomUserManager()
>     class Meta:
>         abstract = True
>
>
> class Customer(User):
>     customer_specific_fields = ...
>
>
> class Merchant(User):
>     merchant_speicifc_fields = ...
>
>

Yes this is exactly what I was thinking. You were asking about avoiding
MTI, and this is how you would do it.



> In this case, what would be AUTH_USER_MODEL? If i am not wrong, an
> abstract base class cannot be an AUTH_USER_MODEL.
>
>
Ah, now we get back in to Carl's original answer and why having a single
(probably custom) user class with a separate profile table makes sense.
Obviously you can't point AUTH_USER_MODEL at the abstract class, leaving
you with a choice about whether you want Customer's or Merchant's to be the
target of AUTH_USER_MODEL. Not ideal either way. It was unclear to me
whether or not you were going to use the default auth backends to log both
types of users in, or if those were simply storage models, with the actual
users who log in to the system in a separate model (which is where
AUTH_USER_MODEL would be pointing).

You could have a single CustomUser class that has a static choices=((1,
'Customer'),(2,'Merchant')) for a particular field so that a DB hit is not
involved whenever the user is pulled to make the determination as to the
type of user. Not very flexible, but cheap to process.

If you are planning on having a ton of fields added to your CustomUser
class, I would highly recommend you take the DB hit and create a separate
set of related models to a single CustomUser (similar to the profile idea
that Carl mentioned). That way you aren't returning a ton of data for every
single request, which can get expensive in the long run, even with only
using a single query.

# models.py
class CustomUser(AbstractBaseUser, PermissionsMixin):
    # small number of fields needed for almost every single request
    # should rarely change structure via migrations

class CustomerData(models.Model):
    # OneToOne back to CustomerUser
    # Other fields that are not necessarily needed for every request,
loaded on demand
    # may be often modified by migrations

class MerchantData(models.Model):
    # OneToOne back to CustomerUser
    # Other fields that are not necessarily needed for every request,
loaded on demand
    # may be often modified by migrations

# settings.py
AUTH_USER_MODEL = 'myapp.models.CustomUser'


Note that you'll want your AUTH_USER_MODEL to change as little as possible
in production. Errors in that model will often have a far-reaching effect.
The two Data models will likely change more often, and will probably have
less of an impact in the event of an issue with a migration.

As Carl mentioned the 2Scoops authors were not saying that OneToOne
relationships were bad and to never use them, they just don't like the
'implied' OneToOne relationships Django creates when MTI is used. OneToOne
fields are not something that should be made scary, rather, they should
simply be made explicit in the code.

-James

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CA%2Be%2BciWQX79p7NPtd1dSowne7G6LkVeha%2Bmc4bdnDq-eP3Ok9w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to