I want to implement django signals on User model for create user profile. I want to create user profile when any user will be registered. here is my code for create user profile though signals:
from django.contrib.auth.models import User
#receiver(post_save, sender=User)
def user_is_created_or_save(sender,instance,created,**kwargs):
user = instance.user
first_name = instance.first_name
last_name = instance.last_name
if created:
UserProfile.objects.create(user=user)
I am not understanding why user profile not creating when any user registered?
#updated question
I am using Abstract user model. here is my user mdoel:
class UserManagement(AbstractUser):
is_blog_author = models.BooleanField(default=False)
is_editor = models.BooleanField(default=False)
is_subscriber = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
class Subscriber(models.Model):
user = models.OneToOneField(UserManagement, on_delete=models.CASCADE, primary_key=True)
email = models.EmailField(max_length=1000)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
is_subscriber = models.BooleanField(default=False)
class UserProfile(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,related_name="userprofile")
Since a custom user model has been defined, you can't use from django.contrib.auth.models import User. It is also not a recommended way to reference the user model.
As described in the docs if you have properly setup your custom user model, you can use settings.AUTH_USER_MODEL to reference your custom user model as the sender:
from django.conf import settings
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def user_is_created_or_save(sender, instance, created, **kwargs):
...
Related
I have a custom user model in my Django project and when I create an instance of request.user in my views PyCharm doesn't seem to recognize the user instance correctly. The available methods/attributes suggested by PyCharm still point to the built-in Django user model but not to my new one.
Is there any way to set this up properly?
Example:
# settings.py
AUTH_USER_MODEL = 'user.UserProfile'
# models.py custom user model
class UserProfile(AbstractBaseUser, PermissionsMixin):
# Email and name of the user
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
# Privilege and security booleans
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
email_confirmed = models.BooleanField(default=False)
# Company on whose behalf the user acts on
company = models.ForeignKey('company.Company', on_delete=models.CASCADE, blank=True, null=True)
objects = UserProfileManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def email_user(self, subject, message, from_email=None, **kwargs):
"""Send mail to user - Copied from original class"""
send_mail(subject, message, from_email, [self.email], **kwargs)
def __str__(self):
return self.email
# views.py
def render_dashboard_benefits(request):
# Get current user instance
current_user = request.user
# Typing...
current_user.company
# Pycharm suggests 'first_name' and 'last_name' depending on the initial user model
# but not e.g. "email" or "company" according to the new user model
return render(request, 'test.html')
Re dudulus answer, this indeed works but raises:
current_user: UserProfile = request.user
so still I think this is an IDE bug?
You can use like this.
current_user: UserProfile = request.user
I am trying to make a user Signup system along with his profile.
my models.py:
class myCustomeUser(AbstractUser):
username = models.CharField(max_length=50, unique="True", blank=False)
password = models.CharField(max_length=200, blank=False)
USERNAME_FIELD = 'username'
class Profile(models.Model):
user = models.OneToOneField(myCustomeUser, null=True, on_delete=models.CASCADE)
bio = models.TextField()
profile_pic = models.ImageField(null=True, blank=True, upload_to="images/profile/")
my forms.py:
class SignUpForm(ModelForm):
class Meta:
model = Profile
fields = '__all__'
my views.py:
class index(generic.CreateView):
form_class = SignUpForm
template_name = 'index.html'
Now here my problem is, the form gives me an option to choose any user (with dropdown) to create a profile.... but I want to create a user also on that page (not pick an option from dropdown). How can I try for that?
Your need to connect your user creation form with Django post_Save signals.
I will point out a tutorial that can assist you
https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html
Your signup form should use myCustomeUser
So that you create a user first
Then.with the help of "signals" you can create profiles automatically every time a user is created
this is my models.py
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
mobile = models.CharField(max_length=12)
first_name=models.CharField(max_length=20)
last_name=models.CharField(max_length=20)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['mobile','first_name','last_name']
class Customer(models.Model):
user=models.OneToOneField(MyUser,null=True,blank=True,on_delete=models.CASCADE)
name=models.CharField(max_length=100,null=True)
email=models.CharField(max_length=100)
mobile=models.CharField(max_length=12)
def __str__(self):
return self.name
class Order(models.Model):
customer=models.ForeignKey(Customer,on_delete=models.SET_NULL,null=True,blank=True)
date_ordered=models.DateTimeField(auto_now_add=True)
complete=models.BooleanField(default=False,null=True,blank=False)
transaction_id=models.CharField(max_length=100,null=True)
and this is my views.py
def signup(request):
if request.method == "POST":
first_name=request.POST['first_name']
last_name=request.POST['last_name']
email=request.POST['email']
mobile=request.POST['mobile']
password=request.POST['password']
cpassword=request.POST['cpassword']
if password==cpassword:
if User.objects.filter(email=email).exists():
messages.info(request,'Email already in use')
return redirect('signup')
elif User.objects.filter(mobile=mobile).exists():
messages.info(request,'Mobile Number already in use')
return redirect('signup')
else:
user=User.objects.create_user(first_name=first_name,last_name=last_name,email=email,password=password,mobile=mobile)
customer=Customer(user=user.email,mobile=mobile,name=first_name)
customer.save();
user.save();
return redirect('/login/')
else:
messages.info(request,'Passwords not matching')
return redirect('signup')
else:
return render(request,'signup.html')
I am working on a basic e-commerce website and to access the shopping cart the user must be registered.
The other model i am using is Order and which has a foreign key as customer.So basically to access the cart one has to be the customer.
The signup page that i have registers the users but also at the same time I want to make him/her a customer as well but i am not able to do it.
I tried using this
customer=Customer(user=user.email,mobile=mobile,name=first_name)
customer.save();
but i am getting error.
Please suggest some way so that whenever someone registers there is a customer object automatically created for him so that he can access the cart.
(i can manually set a customer in localhost/admin but thats extremely inefficient)
Following is a basic example.
Create signals.py file inside your app where models.py is located.
from django.contrib.auth import get_user_model
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
# User = get_user_model()
User = settings.AUTH_USER_MODEL
#receiver(post_save, sender=User)
def create_customer(sender, instance, created, **kwargs):
if created:
Customer.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_customer(sender, instance, **kwargs):
instance.customer.save()
I have made a signup page using built in UserCreationForm of django.
signup.html
class UserCreationForm(UserCreationForm):
email = EmailField(label=_("Email address"), required=True, help_text=_("Required."))
class Meta:
model = User
fields = ("username", "email", "password1", "password2")
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user
But I also need to make other tables in models.py. So if in another table category I need to make a foreign key of the primary key of this built in User of UserCreationForm. What is the primary key in this?
models.py
class category(models.Model):
uid = models.ForeignKey(#)
cname = models.CharField(max_length=20)
def __unicode__(self):
return u"{} {}".format(self.uid, self.cname)
class Meta:
db_table = "category"
What do I write in place of # ??
Just point to the User model:
from django.contrib.auth import User
uid = models.ForeignKey(User)
or better, in case you might want to customise the User model:
from django.conf import settings
uid = models.ForeignKey(settings.AUTH_USER_MODEL)
The error I get is: extend user to a custom form, the "user_id" field is my custom form is the "property", which is linked to the table "auth_user" is not saved, and I need both tables relate to make use my custom form attributes and shape of the User of django.
my models.py
from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
Matricula = models.CharField(max_length=25)
forms.py
class SignupForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('first_name', 'last_name', 'Matricula')
#Saving user data
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.Matricula = self.cleaned_data['Matricula']
user.save()
##Save profile
profile = Profile()
Profile.user = user
profile.Matricula = self.cleaned_data['Matricula']
profile.save()
i tried:
user = models.OneToOneField(User, on_delete=models.CASCADE)
but I get an error:
Error
You believe that ForeignKey can be used or correct use OneToOneField?
You should be careful with your capitalisation. You've assigned the user value to the class, not the instance. It should be:
profile = Profile()
profile.user = user
Or better:
profile = Profile(user=user)
You are not setting user to that instance of Profile:
profile = Profile()
profile.user = user # Notice the case of Profile