Store checkbox value in db's new column - react/django - django

I've been trying to store value of one checkbox, promo_consent, sent from a form into a new column that I've just created in the DB.
Whatever I do it stores always TRUE no matter wheter the checkboxed was checked or not, or stores always FALSE no matter wheter the checkboxes was checked or not.
I have this model:
class User(AbstractBaseUser, PermissionsMixin, PagePermissionMixin):
"""User model for both staff and clients.
It consists of base AbstractBaseUser class and has 2 permissions mixins.
One of them is for standard django permissions and the second is
for Page object permissions.
Note:
This model is used for OAuth2 and Django authentication.
"""
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('email address'), unique=True, blank=True)
new_email = models.EmailField(_('new email'), 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)
promo_consent = models.BooleanField(
_('Promo consent'),
default=False,
help_text=_('Shows whether user has agreed to be notified about '
'news and promo sales'))
....
....
....
and this serializer:
class RegistrationSerializer(SerializerSchemaMixin, serializers.Serializer,
SerializerValidateMixin,
EmailUniquenessValidationMixin,
PasswordValidationMixin):
"""Registration serializer."""
first_name = serializers.CharField(max_length=30, default='')
last_name = serializers.CharField(max_length=30, default='')
email = serializers.EmailField(required=True)
password = serializers.CharField(max_length=100, required=True)
password2 = serializers.CharField(max_length=100, required=True)
rules = serializers.BooleanField(required=True)
promo_consent = serializers.BooleanField(required=False)
def validate_rules(self, value):
"""Checks if 'rules' is True."""
if not value:
raise serializers.ValidationError(_('Rules has to be checked'))
else:
return value
def promo_consent(self, value):
return true
def validate(self, data):
"""Override serializer.validate()."""
self.validate_passwords_uniformity(data)
return data
def save(self, **kwargs):
"""Register new user and send confirmation email."""
language = kwargs['language']
email = self.validated_data['email']
promo_consent = self.promo_consent
self.instance = User(first_name=self.validated_data['first_name'],
last_name=self.validated_data['last_name'],
email=email,
is_active=False,
email_confirmation=uuid.uuid4().hex)
self.instance.set_password(self.validated_data['password'])
self.instance.save()
self.instance.send_email_confirmation(language, email)
return self.instance
I've been working this the second day. What am I missing here?

Related

rest_framework.request.WrappedAttributeError: 'AccountManager' object has no attribute 'get'

I am working on my Django project, I am getting this error but i don't really know how to fix it exactly, i have created my custom user model and the user manager
class AccountManager(BaseManager):
def create_user(self, email, fullname=None, birthday=None,zipcode=None, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(Email_Address=self.normalize_email(email),
name=self.normalize_email(email),
Date_of_Birth=birthday,
zipcode=zipcode
)
user.set_password(password)
user.save(using='self._db')
return user
def create_superuser(self, Email_Address, username, password):
user=self.create_user(Email_Address=self.normalize_email(Email_Address), password=password,)
user.is_admin = True
user.is_active = True
user.is_staff = True
user.is_superuser = True
user.save(using='self._db')
class User(AbstractUser):
Email_Address = models.EmailField(verbose_name='email', unique=True, blank=True, null=True)
Date_of_Birth = models.CharField(max_length=30, blank=True, null=True, default=None)
name = models.CharField(max_length=30, blank=True, null=True)
username= models.CharField(max_length=30,unique=True, blank=True, null=True)
zipcode = models.CharField(max_length=30, blank=True, null=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'Email_Address'
objects = AccountManager()
REQUIRED_FIELDS = ['username']
def __str__(self):
return self.username
because i am using rest_framework_simplejwt for authentication i am getting this error when i try to log in
user = self.user_model.objects.get(**{api_settings.USER_ID_FIELD: user_id})
rest_framework.request.WrappedAttributeError: 'AccountManager' object has no attribute 'get'
can anyone please help me with this
According to this section, https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#writing-a-manager-for-a-custom-user-model, you need to extend your custom user manager from BaseUserManager.
In your code you extended from the BaseManager.

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

How to access reverse relationship in django models?

I have two models one for User and another for storing CustomerInfo(user of type customer).
class User(AbstractBaseUser):
"""
This is a class for user table which overrides functionalities of default django user model.
Attributes:
name (CharField): Name of a user.
email (EmailField): Email address of a user.
mobile (CharField): Phone number of a user.
date_joined (CharField): When a user was added.
last_login (CharField): Last login date time of a user.
is_admin (CharField): If user is a admin or not.
is_active (CharField): If user is active or not.
is_staff (CharField): If user is staff or not.
is_superuser (CharField): If user is a superuser or not.
role (OneToOneField): One to one relationship with role table.
"""
name = models.CharField(max_length=80)
email = models.EmailField(max_length=255, unique=True)
mobile = models.CharField(
validators=[
RegexValidator(
regex=r"^\d{10,14}$",
message="Phone number must be entered in format: '+999999999'. Up to 14 digits allowed.",
)
],
max_length=15,
unique=True,
)
role = models.ForeignKey(Role, on_delete=models.SET_NULL, null=True)
drivers = models.ManyToManyField(
"self", through="DispatcherDriver", symmetrical=False
)
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
USERNAME_FIELD = "mobile"
REQUIRED_FIELDS = ["email", "name"]
objects = UserManager()
class Meta:
db_table = "users"
def __str__(self):
return self.name
# For checking permissions. to keep it simple all admin have ALL permissons
def has_perm(self, perm, obj=None):
return self.is_admin
# Does this user have permission to view this app? (ALWAYS YES FOR SIMPLICITY)
def has_module_perms(self, app_label):
return True
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
class CustomerInfo(models.Model):
customer = models.OneToOneField(
User, on_delete=models.CASCADE, primary_key=True, related_name="customer_info"
)
company_name = models.CharField(max_length=255)
class Meta:
db_table = "customer_info"
def __str__(self):
return self.company_name
CustomerInfo model has OneToOneField mentioned in the model. How can I access CustomerInfo of a User model using reverse relationship?
Suppose, you has User's instance user then you can fetch customer_info as
from django.core.exceptions import ObjectDoesNotExist
try:
customer_info = user.customer_info
except ObjectDoesNotExist:
print("There is no customer info here.")
Reference - https://docs.djangoproject.com/en/3.1/topics/db/examples/one_to_one/
Try:
myuser = User.objects.create(email="..", name="..", password="1223")
profile = CustomerInfo.objects.create(customer=myuser)
company_name = myuser.customer_info.company_name

How to properly extend Django user?

I want to extend the Django user class in Django 1.7.1 to drop the first name and last name and to put a unique constraint on the e-mail address. So far I have this custom model to change the constraints/fields:
class ExtUser(AbstractBaseUser, PermissionsMixin):
class Meta:
# Django 1.7.2?
#default_related_name = 'user'
db_table = 'auth_user'
verbose_name = _('user')
verbose_name_plural = _('users')
abstract = False
username = models.CharField(_('username'), max_length=30, unique=True,
help_text=_('Required. 30 characters or fewer. Letters, digits and '
'#/./+/-/_ only.'),
validators=[
validators.RegexValidator(r'^[\w.#+-]+$', _('Enter a valid username.'), 'invalid')
])
email = models.EmailField(_('email address'), max_length=75, blank=False, null=False, unique=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()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
def get_short_name(self):
return self.username
def email_user(self, subject, message, from_email=None, **kwargs):
send_mail(subject, message, from_email, [self.email], **kwargs)
And I modified the settings file:
AUTH_USER_MODEL = 'ext.ExtUser'
I can login to the Django admin, but when I try to edit a user, I get the following exception:
ProgrammingError at /api/extuser/1/
column auth_user_groups.extuser_id does not exist
LINE 1: ...oup"."id" = "auth_user_groups"."group_id" ) WHERE "auth_user...
I guess the user foreign key in other tables is formed based upon the class name... How do I fix this? I tried using the default_related_name field in the model meta class, but that had no positive effect.
Thanks in advance for any help!
Kind regards,
K.
OK, so I found a solution for my problem: make sure that the custom user model class is named "User" instead of "ExtUser" and everything will keep on working.
Easy! :-)

django social auth not returning first_name and last_name when creating a profile - django 1.5

Am using a custom user model to maintain user details with django 1.5, below is my code. When using social auth, everything seems to be working fine accept first_name and last_name.
In my table table structure, I do not have first_name and last_name, instead, I have one field full name.
but, i did create a method in the manager to accept first and last names and combine them. but, still am receiving empty values, any advise on why this is happening?
class UserManager(BaseUserManager):
"""
UserManager()
"""
def create_user(self, username, email=None, password=None, first_name='', last_name='', **extra_fields):
if not username:
raise ValueError('Users must have a username')
user = self.model(
username=username,
email=UserManager.normalize_email(email),
full_name='%s %s' % (first_name, last_name),
)
user.set_password(password)
user.save(using=self._db)
return user
class User(AbstractBaseUser, PermissionsMixin):
"""
Accounts/User
"""
GENDERS = (
(u'M', _('Male')),
(u'F', _('Female')),
)
username = models.CharField(_('username'), max_length=30, unique=True,
help_text=_('Required. 30 characters or fewer. Letters, numbers and '
'#/./+/-/_ characters'),
validators=[
validators.RegexValidator(re.compile('^[\w.#+-]+$'), _('Enter a valid username.'), 'invalid')
])
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)
# user details and information
full_name = models.CharField(_('full name'), max_length=30, )
date_of_birth = models.DateField(_('birthday'), null=True, blank=True)
bio = models.TextField(_('biography / about you'), null=True, blank=True, help_text=_('Biography / About you'))
gender = models.CharField(_('gender'), max_length=1, blank=True, null=True, choices=GENDERS)
# follows / followers
followings = models.ManyToManyField('self', through='Relationship', symmetrical=False, related_name='followers')
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'date_of_birth', 'full_name',]
Django-social-auth doesn't work like that when creating user, instead when calling create_user in your manager, it just passes the username and the email as you can see here. Later in the pipeline more fields in your user model are update when this is called, but as the code says, it does a getattr(user, name, None) which in you case for first_name and last_name, returns None since those fields aren't defined in your model.
You can trick the system by defining some properties in your model, something like this:
class User(...):
#property
def first_name(self):
if not hasattr(self, '_first_name'):
self._first_name = self.full_name.split(' ', 1)[0]
return self._first_name
#first_name.setter
def first_name(self, value):
self._first_name = value
self.build_full_name()
#property
def last_name(self):
if not hasattr(self, '_last_name'):
self._last_name = self.full_name.split(' ', 1)[-1]
return self._last_name
#first_name.setter
def last_name(self, value):
self._last_name = value
self.build_full_name()
def build_full_name(self):
self.full_name = ' '.join([self._first_name, self._last_name])