First off this may not be the best way to set this up, however, I'm learning as I go and struggling to find the correct answer.
I have an Account app which handles the user signup, I added the couple_choice option which I'm trying to get in another app's model.
ACCOUNT model
class Account(AbstractBaseUser):
COUPLE_CHOICE = Choices('single', 'couple')
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', 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)
profile_image = models.ImageField(max_length=255, upload_to=get_profile_image_filepath, null=True, blank=True, default=get_default_profile_image)
hide_email = models.BooleanField(default=True)
couple_choice = models.CharField(choices=COUPLE_CHOICE, default='single', max_length=20)
I then have another app Profile, which I want to make the couple = True if the Account.account.couple_choice, is 'couple' then Profile.couple = True
from account.models import Account
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,blank=True, null=True, related_name="swinger")
couple = models.BooleanField(default=False)
admin.py
from django.contrib import admin
from profile.models import Profile
from account.models import Account
#admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if Account.objects.filter(username=request.user.username).exists():
account = Account.objects.get(username=request.user.username)
if account.couple_choice == 'couple':
obj.couple = True
super().save_model(request, obj, form, change)
Please let me know the best way to do this?
Thanks
if you set the Profile.couple = True, you must define couple as boolean. To achieve your aim, you should control the Account.couple_choise when user save profile. You can do this if you have ModelAdmin class in admin.py like
#admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if Account.objects.filter(email=request.user.email).exists()
account = Account.objects.get(email=request.user.email)
if account.couple_choice == 'couple'
obj.couple = True
super().save_model(request, obj, form, change)
Related
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
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
i created a custom form from the Django-allauth package adding a first name, Lastname and is_staff. This was after i had extended the user model using abstart user. i think it has something to do with is_staff being a boolean value. All suggestions are welcome. thank you.
My user model looks like this
from django.contrib.auth.models import AbstractUser, UserManager
class CustomUserManager(UserManager):
def get_by_natural_key(self, username):
case_insensitive_username_field = '{}__iexact'.format(self.model.USERNAME_FIELD)
return self.get(**{case_insensitive_username_field: username})
class User(AbstractUser):
is_student = models.BooleanField('student status', default=False)
location = models.CharField(max_length=30, blank=True)
# first_name= models.CharField( blank=False, max_length=30, verbose_name='first name')
email = models.EmailField(unique=True)
objects = CustomUserManager()
My custom form is as shown below
from django.contrib.auth.models import User, Group
class CustomSignupForm(SignupForm):
first_name = forms.CharField(max_length=30, label='First Name')
last_name = forms.CharField(max_length=30, label='Last Name')
is_staff = forms.BooleanField(required=True ,label = 'Are you been assigned as a staff?')
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
return user
Update your signup method and add the following line before save,
user.is_staff = self.cleaned_data['is_staff']
I am using graphql in my project and want to generate token while registration. Even though django-graphql-auth has all the written mutation, it uses a different user model. But I want to use my custom user model. What should I do?
This is my user model
class CustomUser(AbstractUser):
"""
Customized User Model
"""
email = models.EmailField(blank=True, null=True,
max_length=256, unique=True)
mobile_no = models.CharField(
max_length=20, blank=True, null=True, unique=True)
verification_code = models.CharField(max_length=6)
code_valid_till = models.DateTimeField(blank=True, null=True)
timezone = models.CharField(max_length=40, blank=True, null=True)
country = models.CharField(max_length=20, default='BD', choices=COUNTRIES)
pin_verified = models.BooleanField(default=False)
email_verified = models.BooleanField(default=False)
modified_on = models.DateTimeField('date modified', auto_now=True)
created_on = models.DateTimeField(auto_now_add=True)
# For password reset
reset_verification_code = models.CharField(
max_length=6, blank=True, null=True)
reset_code_valid_till = models.DateTimeField(blank=True, null=True)
reset_request = models.BooleanField(default=False)
reset_valid_till = models.DateTimeField(blank=True, null=True)
class Meta:
verbose_name_plural = "User"
def __str__(self):
if not self.is_anonymous:
return "{} - {}".format(self.mobile_no, self.email)
else:
return "Anon"
#property
def get_full_name(self):
return super().get_full_name()
def get_all_permissions(self, obj=None):
return super().get_all_permissions(obj=obj)
def send_email(self, subject, message, to_email: list, from_email=None, **kwargs):
send_mail_to_user(subject, message, from_email, to_email, **kwargs)
I'm the author of the package. Now the documentation site has a custom user model in the quickstart, you can see it here. Currently, it's not documented how to use it with a custom user model, but it is already an open issue, you can see it here. I will paste the same answer that is on the Github.
From Django docs:
Changing to a custom user model mid-project
Changing AUTH_USER_MODEL after you’ve created database tables is
significantly more difficult since it affects foreign keys and
many-to-many relationships, for example.
So, make sure to create the custom user model when you start your project.
Add the following to your custom user model
Following the Django custom user model.
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
# ...
USERNAME_FIELD = "<username_filed_name>" # e.g: "username", "email"
EMAIL_FIELD = "<email_field_name>" # e.g: "email", "primary_email"
Add your custom user model in the settings
See here for more info.
# settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'
Please let me know if you have further questions :)
Edit: Add the mobile_no in the registration
Use the REGISTER_MUTATION_FIELDS or REGISTER_MUTATION_FIELDS_OPTIONAL.
# settings.py
GRAPHQL_AUTH = {
# ...
REGISTER_MUTATION_FIELDS = [
# ...
'mobile_no'
]
# or
REGISTER_MUTATION_FIELDS_OPTIONAL = ['mobile_no']
# You can set the graphene base scalars:
REGISTER_MUTATION_FIELDS = {
"email": "String",
"username": "String",
"mobile_no": "String",
}
}
I have a custom model with which I am trying to authenticate:
class User(models.Model):
#id = models.IntegerField(primary_key=True)
#identifier = models.CharField(max_length=40, unique=True, db_index=True)
username = models.CharField(max_length=90, unique=True, db_index=True)
create_time = models.DateTimeField(null=True, blank=True)
update_time = models.DateTimeField(null=True, blank=True)
email = models.CharField(max_length=225)
password = models.CharField(max_length=120)
external = models.IntegerField(null=True, blank=True)
deleted = models.IntegerField(null=True, blank=True)
purged = models.IntegerField(null=True, blank=True)
form_values_id = models.IntegerField(null=True, blank=True)
disk_usage = models.DecimalField(null=True, max_digits=16, decimal_places=0, blank=True)
#last_login = models.DateTimeField()
objects = UserManager()
USERNAME_FIELD = 'username'
#check_password(password)
class Meta:
db_table = u'galaxy_user'
I have mentioned this in `settings.
AUTH_USER_MODEL = 'fileupload.user'
#views.py
def login_backend(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect('/overview/')
else:
return HttpResponseRedirect('/login_backend/')
else:
return render_to_response('login_backend.html', context_instance=RequestContext(request))
However I am getting this error:
AttributeError: 'User' object has no attribute 'check_password' error
What am I doing wrong?
As described in the custom user documentation, your User model must inherit from django.contrib.auth.models.AbstractBaseUser, which adds all the relevant methods.
In the documentation for Django 1.5 (which is the first one with AUTH_USER_MODEL) shows the method the alternative User model must have, and one of them is check_password. So, IMO, you have two ways for solving your issue.
Substitute the User model properly providing all required methods.
Forget about substituting the User model and just write a custom AUTH BACKEND without including "AUTH_USER_MODEL"
Get the Django 1.5 RC. And follow these instructions on writing a custom User class.
Add from django.contrib.auth.hashers import check_password after get_user_model