Tuesday, 5 November 2019

Django --->> settings.py --->> AUTH_USER_MODEL =























This blog post as most others here is in a "notes to myself" category , in case its useful to any other reader - well thats great , i dont really have the time to create very readable user focused content as on date .

Use case is simple - creating USER PROFILE's which will add  Parameters to the DJANGO USER - parameter's such as DEPARTMENT / SUB DEPARTMENT / BIODATA etc . Will use this to classify users at time of REGISTRATION itself. Will use this Meta-data to restrict visibility to content - utilizing the built in django.contrib.auth.mixins , specifically / initially using - LoginRequiredMixin and the UserPassesTestMixin.

As of now anyone can REGISTER on DigitalCognition by providing a NON- UNIQUE email ID and an UNIQUE USERNAME . The Non Unique email id is a historical / legacy Django thing and am not going to change that as on date - as i do suppose there will always be a need to have Multiple User Logins for the same email ID - both for testing and production. Also as most users have to go through the ADMIN APPROVED ACCOUNTS LOGIN https://digitalcognition.co.in/admin_approved_accounts/register/ to reach the Landing page which as on date is at URL  https://digitalcognition.co.in/dc/datasets_listView/,.


Quoting from the official Django docs -


Extending the existing User model

There are two ways to extend the default User model without substituting your own model. If the changes you need are purely behavioral, and don’t require any change to what is stored in the database, you can create a proxy model based on User. This allows for any of the features offered by proxy models including default ordering, custom managers, or custom model methods.

Am going to try the various approaches mentioned below and will stop at whatever works for me for now as an interim , may get back to further tweaking later :- 

 1 Create a PROXY User Model- proxy_user_model - based on the official Django , model named User which exists at path - /home/dhankar/anaconda2/envs/demo_venv/lib/python3.6/site-packages/django/contrib/auth/models.py



2. Adding Profile Features like a BIODATA or a DEPARTMENT to the existing default User Model - This is not a recommended approach and the Django official docs and lots of other sources on the internet actually recommend against this . Within this there are again two paths to take- the easier one is recommended to be to subclass the AbstractUser . On various sources what is recommended is to subclass the AbstractUser and not try to subclass the AbstractBaseUser. Making changes of any kind to AbstractBaseUser will require more effort and also may mess-up other methods . To begin with in place of creating another custom user class which will sub-class the AbstractUser I will make changes within the default User model.  
The first challenge is to save within the psqlDB/PostGreSQL the input given by the user for a dummy biodata text field - initial code is as seen below.


class AbstractUser(AbstractBaseUser, PermissionsMixin):
"""
FOO - Its recommended to SubClass the AbstractUser Class and create own CustomUser Class like so -
class CustomUser(Abstractuser):
additional_user_fields = bio
FOO --- Im directly adding --->> additional_user_fields = bio , in here into the --- class AbstractUser
"""

"""
An abstract base class implementing a fully featured User model with admin-compliant permissions.
Username and password are required. Other fields are optional.
"""
username_validator = UnicodeUsernameValidator()
help_text_str_username = format_html('<div style="color:grey;"> {} <strong><b>{}</b></strong> {}</div>', 'Username is a Required Field. Your UserName for' , 'DigitalCognition', 'can have max - 150 characters. You may use Letters, digits and @/./+/-/_ only.')

username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text = help_text_str_username,
#help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists within the DigitalCognition user database , kindly choose another username."),
},
)

bio = models.TextField(
_('bio'), #FOO_bio
max_length=500, blank=True)


first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=150, blank=True)
email = models.EmailField(_('email address'), blank=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this admin site.'),
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Unselect this instead of deleting accounts.'
),
)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

objects = UserManager()

EMAIL_FIELD = 'email'
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']

class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
abstract = True

def clean(self):
super().clean()
self.email = self.__class__.objects.normalize_email(self.email)

def get_full_name(self):
"""
Return the first_name plus the last_name, with a space in between.
"""
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()

def get_short_name(self):
"""Return the short name for the user."""
return self.first_name

def email_user(self, subject, message, from_email=None, **kwargs):
"""Send an email to this user."""
send_mail(subject, message, from_email, [self.email], **kwargs)


class User(AbstractUser):
"""
Users within the Django authentication system are represented by this
model.

Username and password are required. Other fields are optional.
"""
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
# FOO --swappable- https://stackoverflow.com/questions/22025476/what-is-swappable-in-model-meta-for


Some excellent explanations from SO almost 7 years back - asto whats with the Django - save(commit = False)

def save(self, commit=True):
user = super().save(commit=False)


https://stackoverflow.com/questions/12848605/django-modelform-what-is-savecommit-false-used-for

My current challenge is slightly diff , am trying to understand the flow of information - so to say .

Have posted two more questions on SO , have accepted one of the answers which led me to further learn the concepts / things mentioned below -

1/ The cleaned_data , dictionary ---...........

def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
#bio = self.cleaned_data.get("bio") # Wont work
#print(bio) #prints None - as there is no BIO key within DICT - cleaned_data
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
return password2











https://stackoverflow.com/questions/58770395/django-usermanagerbaseusermanager-question-why-wont-the-email-and-userna

SO Accepted Answer -- https://stackoverflow.com/a/58736034/4928635


Further when we have a look at the official Django tests for the UserModel and also look at the GitBlame / Change history for the code we can clearly see - these UserModel codes have been around for almost past seven years !!

https://github.com/django/django/blame/ec9d0123e0bf17b6219630ebe1c5f7240acc2743/tests/auth_tests/models/custom_user.py#L36



Further reading required  

Custom User Model + User Profile Model
https://testdriven.io/blog/django-custom-user-model/
https://www.codingforentrepreneurs.com/blog/how-to-create-a-custom-django-user-model
https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html
https://stackoverflow.com/questions/57244525/extending-abstractbaseuser-not-hitting-modelbackend-django

https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#changing-to-a-custom-user-model-mid-project
https://medium.com/@judegyeongbaejung/django-shortcuts-custom-user-models-a3e34ea3d689
https://django-improved-user.readthedocs.io/en/latest/_modules/django/contrib/auth/base_user.html
DJANGO MODULE --- Django Improved User ---- https://django-improved-user.readthedocs.io/en/latest/_modules/django/contrib/auth/base_user.html
https://docs.djangoproject.com/en/2.2/ref/contrib/auth/
https://stackoverflow.com/questions/24321308/django-forms-cleaned-data-missing-certain-fields?rq=1
https://stackoverflow.com/questions/48987669/django-can-i-omit-savecommit-false-in-this-case

FOO---->> https://stackoverflow.com/a/9658211/4928635
https://www.caktusgroup.com/blog/2019/04/26/how-switch-custom-django-user-model-mid-project/
Burhan Khalid --->> https://stackoverflow.com/a/25842236/4928635
https://wsvincent.com/django-referencing-the-user-model/
CUSTOM_USER_MODEL
 FOO MAIN ---- https://wsvincent.com/django-custom-user-model-tutorial/


DJANGO Official -
-->> MAIN  --- https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#substituting-a-custom-user-model
https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#auth-custom-user
https://docs.djangoproject.com/en/2.1/topics/auth/default/#topics-auth-creating-users
https://docs.djangoproject.com/en/2.1/ref/contrib/auth/
https://github.com/django/django/tree/b9cf764be62e77b4777b3a75ec256f6209a57671/tests/auth_tests/models


Django ---- User Profile --->> https://simpleit.rocks/python/django/adding-users-to-your-django-project-with-custom-user-model/
 UserPassesTestMixin ---->> https://github.com/search?l=Python&q=UserPassesTestMixin&type=Code
The UserPassesTestMixin --- test_func(self): ........... https://github.com/venkat0708/BalajiVV/blob/ddf74d26a7ecae3f3bc5a902dcab09bf8f30e448/products/views.py#L37
https://github.com/davehenton/skolagatt/blob/2c2af978906a28ae42502e1777eafc0043a042e8/common/mixins.py#L16


https://stackoverflow.com/a/7313429/4928635
https://stackoverflow.com/questions/47496966/django-multiple-user-profiles-design-decision
UserPassesTestMixin --- https://docs.djangoproject.com/en/2.2/topics/auth/default/#django.contrib.auth.mixins.LoginRequiredMixin
Django Custom User Model --- https://wsvincent.com/django-custom-user-model-tutorial/
FOO MAIN --- https://wsvincent.com/django-rest-framework-user-authentication-tutorial/
#
https://stackoverflow.com/questions/15296863/configure-django-usermanager-to-input-date-of-birth-for-superuser
https://stackoverflow.com/questions/51163088/self-model-in-django-custom-usermanager
https://stackoverflow.com/questions/58735856/django-usermodel-how-to-create-custom-text-field-within-the-django-contrib-a
https://stackoverflow.com/questions/32598287/django-error-saving-user-with-abstractbaseuser-and-baseusermanager
https://stackoverflow.com/questions/51163088/self-model-in-django-custom-usermanager
https://stackoverflow.com/questions/16606312/django-custom-user-model-and-usermanager

 

No comments:

Post a Comment