Django access current user fields from derived class? - django

I have an extended User class, and then a Patient class inherited from it. After the patient logs in I can get first name using request.user.first_name but how can I get the value of address?
models.py:
class User(AbstractUser):
username = None
email = models.EmailField(unique=True)
is_Patient = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = ['password']
object = UserManager()
class Patient(User):
address = models.CharField(max_length=200)
class Meta:
verbose_name_plural = 'Patients'
def __str__(self):
return self.first_name + " " + self.last_name

Found it. We have to use lowercase letters so that:
request.user.patient.address
Instead of:
request.user.Patient.address

Related

Django authentication for custom user, user object always return none if the credential is correct

this is my custom user code
class CustomUser(AbstractUser):
phone_number = models.CharField(max_length=12 , unique=True)
Full_name = models.CharField(max_length=55)
email = models.EmailField(max_length=60,null=True , blank=True)
username = None
first_name = None
last_name= None
USERNAME_FIELD = 'phone_number'
REQUIRED_FIELDS = []
def __str__(self):
return self.Full_name
object = CustomUserManager()
this code is to authenticate user in views.py
user = authenticate(request,phone_number=username,password=password)

Setting password for user model in the admin page

I created a custom User model with multiple roles customers, and employees, where employees also are in different roles: Drivers and administration.
I extended AbstractBaseUser model class to set a customized user model as this:
class UserAccountManager(BaseUserManager):
def create_superuser(self, email, first_name, last_name, password, **other_fields):
other_fields.setdefault("is_staff", True)
other_fields.setdefault("is_superuser", True)
other_fields.setdefault("is_active", True)
other_fields.setdefault("is_driver", True)
other_fields.setdefault("is_customer", True)
other_fields.setdefault("is_responsable", True)
if other_fields.get("is_staff") is not True:
raise ValueError(_("Superuser must be assigned to is_staff."))
if other_fields.get("is_superuser") is not True:
raise ValueError(_("Superuser must be assigned to is_superuser."))
return self.create_user(email, first_name, last_name, password, **other_fields)
def create_user(self, email, first_name, last_name, password, **other_fields):
if not email:
raise ValueError(_("You must provide an email address"))
email = self.normalize_email(email)
user = self.model(email=email, first_name=first_name, last_name=last_name, **other_fields)
user.set_password(password)
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_("Email Address"), unique=True)
first_name = models.CharField(_("First Name"), max_length=150, unique=True)
last_name = models.CharField(_("Last Name"), max_length=150, unique=True)
mobile = models.CharField(_("Mobile Number"), max_length=150, blank=True)
is_active = models.BooleanField(_("Is Active"), default=False)
is_staff = models.BooleanField(_("Is Staff"), default=False)
is_driver = models.BooleanField(_("Is Driver"), default=False)
is_responsable = models.BooleanField(_("Is Responsable"), default=False)
is_customer = models.BooleanField(_("Is Customer"), default=False)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
objects = UserAccountManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["first_name", "last_name"]
class Meta:
verbose_name = "Account"
verbose_name_plural = "Accounts"
def __str__(self):
return self.first_name
and I created two types of models the extend this model which represent each on a different role and inherit from User model:
class Employee(User):
registration_number = models.PositiveSmallIntegerField(_("Driver Registration Number"), unique=True)
picture = models.ImageField(
verbose_name=_("Driver Pic"), help_text=_("Driver Identity Picture"), upload_to="images/driver/"
)
birth_date = models.DateField(_("Date Birth of the Driver"))
city_id = models.ForeignKey("City", blank=True, null=True, on_delete=models.SET_NULL)
bank_id = models.ForeignKey("Bank", blank=True, null=True, on_delete=models.SET_NULL)
class Meta:
verbose_name = "Employee"
verbose_name_plural = "Employees"
def __str__(self):
return self.first_name + " " + self.last_name
class Customer(User):
company_name = models.CharField(_("Company Name"), max_length=150, unique=True)
website = models.CharField(_("Company website"), max_length=150, unique=True)
mobile_2 = models.CharField(_("Mobile Number"), max_length=150, blank=True)
class Meta:
verbose_name = "Customer"
verbose_name_plural = "Customers"
def __str__(self):
return self.first_name + " " + self.last_name
I want to register the models in the admin.py:
#admin.register(User)
class UserAdmin(admin.ModelAdmin):
pass
admin.site.register(Customer)
admin.site.register(Employee)
the problem is that, when I try to add a user from the admin page, I can't set a password for this user, I have a password field that appear when I want to add a new user in any model, but the field seems to be as any normal InputText, the password is visible when it's tapped, and no password is registered in the database.
I would like to add two type of Employee in the model.py :
class Responsable(Employee):
responsability_type = models.CharField(max_length=4, blank=True)
class Meta:
verbose_name = "Responsable"
verbose_name_plural = "Responsables"
def __str__(self):
return self.first_name + " " + self.last_name
class Driver(Employee):
driving_licence = models.ImageField(
verbose_name=_("Driver Licence"), help_text=_("Driver Licence Picture"), upload_to="images/driver_licence/"
)
driver_licence_expiration_date = models.DateField(_("Expiration Date for Driver Licence"))
class Meta:
verbose_name = "Driver"
verbose_name_plural = "Drivers"
def __str__(self):
return self.first_name + " " + self.last_name
I don't know if it's a good idea to design this models for this kind of roles, I want to avoid getting multiple tables with passwords stored in it.
Don' t use model inheritance like that, especially for the custom User model. Creates a unique model that inherits from AbstractBaseUser, that contains the type of the user and that contains all the fields that you have declared in your current tables:
class User(AbstractBaseUser, PermissionsMixin):
class UserTypes(Enum):
customer = ('cu', 'Customer')
responsable = ('re', 'Responsable')
driver = ('dr', 'Driver')
#classmethod
def get_value(cls, member):
return cls[member].value[0]
user_type = models.CharField(max_length=2, choices=[x.value for x in UserTypes])
# Insert fields that are in common between all user types, for example:
email = models.EmailField(_("Email Address"), unique=True)
# Insert fields that could be None depending on the user type, for example:
company_name = models.CharField(_("Company Name"), max_length=150, unique=True, null=True, blank=True)
Then add this in your settings:
AUTH_USER_MODEL = 'yourappname.User'
Your ModelAdmin for managing users should inherit from UserAdmin to allow password management:
#admin.register(User)
class UserAdmin(UserAdmin):
fieldsets = ((None, {'fields': ('email', 'password', 'user_type', 'company_name')})) # Other fields showed when updating an user
add_fieldsets = ((None, {'fields': ('email', 'password', 'user_type', 'company_name')})) # Other fields showed when creating an user

Requiring checking checkbox during in custom Django sign-up form

Im preparing customized Django registration form. I need adding two checkboxes that are required (RODO consent and consent for using images). How to declare in Django that this checkboxes must be checked before form could be send? Form is based on model and it looks like this:
Models.py
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(_('first name'),max_length=50)
last_name = models.CharField(_('last name'),max_length=150)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
RODO_consent = models.BooleanField(default=False)
image_consent = models.BooleanField(default=False)
marketing_consent = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
Forms.py
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = ('email','password1','first_name','last_name','RODO_consent','image_consent','marketing_consent')
You can add custom validation in your CustomUserCreationForm. field_names would be your RODO_consent and image_consent
def clean_field_name(self, field_name):
is_filled = self.cleaned_data.get(field_name)
if not is_filled:
raise forms.ValidationError('This field is required')
return is_filled

Trying to serialize data from multiple models

I am trying to serialize three django models in a section of my api, but it seems he doesn't like the way I do it .. Im following the documentation of https://www.django-rest-framework.org/api-guide/relations/#nested-relationships
I have tried to create 3 serializers one for each model and then put everything together in the fields of the last
serializers.py
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ['name', 'user']
class UserCompanySerializer(serializers.ModelSerializer):
class Meta:
model = UserCompany
fields = ['name']
class UserInfoSerializer(serializers.ModelSerializer):
profile = UserProfileSerializer
companys = UserCompanySerializer(many=True)
class Meta:
model = CustomUser
fields = ['email', 'profile', 'companys']
I thought it would work but it returns the error:
ImproperlyConfigured at /user_info
Field name profile is not valid for model CustomUser.
models.py
class UserCompany(models.Model):
name = models.CharField(max_length=150, unique=True)
def __str__(self):
return self.name
class CustomUser(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
is_active = models.BooleanField(default=False)
companys = models.ForeignKey(UserCompany, on_delete=models.CASCADE, null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
class UserProfile(models.Model):
name = models.CharField(max_length=300, unique=True)
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.name

Creating a group hierarchy in Django

I can't seem to figure out how to best implement a user model following this schema in Django:
All are members, some are staff and must be part of a committee, where each committee has a leader
I'm creating a custom admin interface for my use. I've extended the AbstractBaseUser class to create a new class User that represents all members, but there are some fields that are not relevant to members.
class User(AbstractBaseUser):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
username = models.CharField(max_length=20, unique=True)
date_joined = models.DateTimeField(auto_now_add=True)
email = models.EmailField(max_length=100, default='')
phone_number = models.CharField(default='', blank=True)
balance = models.IntegerField(default=0)
minimum_balance = models.IntegerField(default=0)
status = models.CharField(choices=STATUS, default=STATUS_ACTIVE)
committee = models.CharField(choices=COMMITTEE, default=COMMITTEE_1)
objects = MyUserManager()
USERNAME_FIELD = 'username'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = ['first_name',
'last_name',
'email',]
def get_full_name(self):
return "{0} {1}".format(self.first_name,self.last_name)
def get_short_name(self):
return self.first_name
def __str__(self):
return self.username
These fields are not needed by a regular member:
status = models.CharField(choices=STATUS, default=STATUS_ACTIVE)
committee = models.CharField(choices=COMMITTEE, default=COMMITTEE_1)
Should these fields be included in the User class and be part of a Group, or should they be somewhere else? How can a leader of a committee be represented in this Django model? Also, is there a better way to implement a hierarchy of users like this in Django?
You can create a modal for committee like this.
Class Committee(models.Model):
name = models.CharField(max_length=255, unique=True)
members = models.ManyToManyField(User)
leader = models.ForeignKey(User)
Above models depict there will not be multiple committees with the same name, a committee will have some members and one leader.