Suppress django signal - python

I have been struggling with this for a couple of weeks now and It seems, I can't get it to work.
As you sign up on my website, you are able to create a userprofile and a company. Then, you are able to add members to your company, however the signal just fires everytime and creates empty companies. How do I stop django from doing this?
model.py
class Companyname(models.Model):
company_name = models.CharField(max_length=100, default = '', null=True, blank=True)
user = models.OneToOneField(User, on_delete=models.CASCADE)
description = models.TextField(max_length=10000, default = '', null=True, blank=True)
def __str__(self):
return self.company_name
#receiver(post_save, sender=User)
def update_user_company(sender, instance, created, **kwargs):
if created:
Companyname.objects.create(user=instance)
if instance.companyname.company_name is '':
print("just print this")
else:
instance.companyname.save()
the company gets stored on the userprofile
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
description = models.CharField(max_length=100, default = '', null=True, blank=True)
company = models.ForeignKey(Companyname, null=True, on_delete=models.CASCADE)
role = models.ForeignKey(Role, null=True, on_delete=models.CASCADE)
team = models.ForeignKey(Team, null=True, on_delete=models.CASCADE)
company_admin = models.BooleanField(default=False)
add_user view.py
def add_user(request):
if request.method == 'POST':
form = AddUserForm(request.POST)
if form.is_valid():
company = request.user.userprofile.company_id
form.save()
user = form.save()
user.refresh_from_db()
user.userprofile.company_id = company
user.userprofile.role = form.cleaned_data.get('role')
user.is_active = False
user.save()
register view.py
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.userprofile.description = form.cleaned_data.get('description')
user.companyname.company_name = form.cleaned_data.get('company_name')
user.userprofile.company_id = user.companyname.id
user.save()
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user)
return redirect('/account/my_product')
else:
form = RegistrationForm()
return render(request, 'accounts/reg_form.html', {'form': form})
Hope someone can help :)

Related

Django Signals not creating profile after user registration

I want the profile to be created once the user registration is complete but I am having to create a profile separate for the existing user.
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from main.models import Membership
# Create your models here.
class Profile(models.Model):
membership = models.OneToOneField(
Membership, on_delete=models.CASCADE, related_name="membership", default="null")
user = models.OneToOneField(
User, on_delete=models.CASCADE, related_name="profile")
couple_with = models.OneToOneField(
User, on_delete=models.CASCADE, related_name="couple_with", blank=True, null=True)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
maiden_name = models.CharField(max_length=2, blank="")
street_address = models.CharField(max_length=50)
GENDER_CHOICES = (
('M', 'Male'),
('F', 'Female'),
)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default="Select")
date_of_birth = models.DateField( blank=True, null=True)
address2 = models.CharField(max_length=10)
city = models.CharField(max_length=20)
state = models.CharField(max_length=20)
zip = models.CharField(max_length=5)
country_name = models.CharField(max_length=30)
graduate_year = models.CharField(max_length=4)
def __str__(self):
return(self.first_name + " " + self.last_name)
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
user = instance
print(user)
if created:
profile = Profile.objects.create(user=user)
profile.save()
This is what my views.py looks like. I don't know where am I slipping. It is able to create the user once registered but the profile is never created and Admin has to create the profile manually.
def register_account(request):
# check if the user is already logged in
if request.user.is_authenticated:
return redirect("main:home")
# if not logged in
else:
if request.method == 'POST':
form = RegistrationForm(request.POST or None)
# check if the form is valid
if form.is_valid():
user = form.save(commit=False)
duplicate = False
nonWarhawks = False
# for u in users:
# if user.email == u.email:
# error_message = "Email Already Exists"
# duplicate = True
# break
if User.objects.filter(email=user.email).exists():
duplicate = True
# duplicate check
if duplicate:
return render(request, 'accounts/register.html', {"error_message": "Email Already Exists", "form": form})
user.is_active = False
user.save()
# create profile
user.refresh_from_db()
user.profile.copule_with = None
user.profile.first_name = request.POST.get("first_name")
user.profile.last_name = request.POST.get("last_name")
user.profile.maiden_name = request.POST.get("maiden_name")
user.profile.street_address = request.POST.get("street_address")
user.profile.city = request.POST.get("city")
user.profile.zip = request.POST.get("zipcode")
user.profile.country_name = request.POST.get("country_name")
user.profile.graduate_year = request.POST.get("graduate_year")
print(user.profile.first_name)
user.profile.save()
current_site = get_current_site(request)
mail_subject = 'Activate your account.'
message = render_to_string('accounts/acc_active_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
'protocol': 'http'
})
to_email = form.cleaned_data.get('email')
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
print("Successfully sent email using the sendgrid api")
return HttpResponse('Please confirm your email address to complete the registration')
# return redirect("daily:home")
else:
form = RegistrationForm(request.POST or None)
return render(request, 'accounts/register.html', {'form': form})
Try this outside your Profile class.
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = Profile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
You have included your #receiver signal inside your profile class. A signal based method isn't actually part of the class it involves. Remove the indentation so it is on the same level as your class Profile declaration

How to assign a default choice value to a user when they sign up in django framework

I am writing a logic where when a users creates and account, i want to automatically assign the free membership to them and i know this should be done in the register view but i don't know why it's not working as expected. I still have to manually go to my admin page and manually assign a value to newly created user and that's not what i really wanted.
Models.py
class Membership(models.Model):
MEMBERSHIP_CHOICES = (
('Enterprise', 'Enterprise'), # Note that they are all capitalize//
('Team', 'Team'),
('Student', 'Student'),
('Free', 'Free')
)
PERIOD_DURATION = (
('Days', 'Days'),
('Week', 'Week'),
('Months', 'Months'),
)
slug = models.SlugField(null=True, blank=True)
membership_type = models.CharField(choices=MEMBERSHIP_CHOICES, default='Free', max_length=30)
duration = models.PositiveIntegerField(default=7)
duration_period = models.CharField(max_length=100, default='Day', choices=PERIOD_DURATION)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
def __str__(self):
return self.membership_type
#### User Membership
class UserMembership(models.Model):
user = models.OneToOneField(User, related_name='user_membership', on_delete=models.CASCADE)
membership = models.ForeignKey(Membership, related_name='user_membership', on_delete=models.SET_NULL, null=True)
reference_code = models.CharField(max_length=100, default='', blank=True)
def __str__(self):
return self.user.username
#receiver(post_save, sender=UserMembership)
def create_subscription(sender, instance, *args, **kwargs):
if instance:
Subscription.objects.create(user_membership=instance, expires_in=dt.now().date() + timedelta(days=instance.membership.duration))
views.py
def register(request):
reviews = Review.objects.filter(status='published')
info = Announcements.objects.all()
categories = Category.objects.all()
if request.method == "POST":
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
obj = request.user
get_membership = Membership.objects.get(membership_type='Free')
instance = UserMembership.objects.create(user=obj, membership=get_membership)
messages.success(request, f'Account Successfully created for {username}! You can Login In Now')
return redirect('userauths:login')
elif request.user.is_authenticated:
return redirect('elements:home')
else:
form = UserRegisterForm()
context = {
'reviews': reviews,
'form': form,
'info': info,
'categories': categories
}
return render(request, 'userauths/register.html', context)
in models you need to special a default="..." attribute

Having an option of switching roles and status in a form

I have an employee model entailing the below
class Employee(models.Model):
STATUS = (
('Active', 'Active'),
('Blocked', 'Blocked'),
)
ROLE = (
('Employee', 'Employee'),
('User', 'User'),
)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
password = models.CharField(max_length=200, null=True)
status = models.CharField(max_length=200, null=True,choices=STATUS)
role = models.CharField(max_length=200, null=True, choices=ROLE)
def __str__(self):
return self.first_name
views shown below the update and new form of employee
#login_required(login_url='login')
def deleteProfile(request, pk):
employee = Employee.objects.get(id=pk)
if request.method == "POST":
employee.delete()
return redirect('/')
return render(request, 'accounts/delete_profile.html', 'employee':employee)
#login_required(login_url='login')
def NewEmployeeProfile(request):
form = EmployeeProfileForm()
if request.method == 'POST':
form = EmployeeProfileForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('/')
return render(request, 'accounts/new_employee_profile.html', {'form': form})
As a superuser I would like to have the decision of allocating an employee either the role of User or employee. (Any User can be able to do this once logged in) When having to update or create an employee
Also as a superuser I would like to allocate whether the employee/User has an blocked or active account (so allowing them access when they log in or not) also when having to create an employee (Any User can be able to do this once logged in)
How will this be reflected on to the view.py when it is either updated or created?

Populate OneToOneField after submitting form Django

I wrote the following code which creates a new user and tries to create a profile for that user:
class RegisterForm(UserCreationForm):
email = forms.EmailField(max_length=200, help_text='Required')
class Meta:
model = CustomUser
fields = ('username', 'email', 'password1', 'password2')
#login_required(login_url="/login")
def index(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
profile = Profile().save()
user = form
user.profile = profile
user.save()
return redirect('users')
else:
print(form.errors)
else:
form = RegisterForm()
user_model = get_user_model()
users = user_model.objects.all()
paginator = Paginator(users, 15)
page = request.GET.get('page')
users = paginator.get_page(page)
return render(request, 'users/index.html', {'users': users, 'form': form})
class Profile(models.Model):
has_premium_until = models.DateTimeField(null=True, blank=True)
has_premium = models.BooleanField(default=False)
has_telegram_premium_until = models.DateTimeField(null=True, blank=True)
has_telegram_premium = models.BooleanField(default=False)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
class CustomUser(AbstractUser):
email = models.EmailField(max_length=255, unique=True)
profile = models.OneToOneField(Profile, on_delete=models.CASCADE, null=True)
When I'm submitting the form the user as well as the profile is created but the profile is not stored in the user (the profile_id stays null).
Anyone who can help me out?
Your user is actually just a reference to the ProfileForm you constructed. You can obtain the user that has logged in with request.user. So you can update the user with:
#login_required(login_url='/login')
def index(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
profile = Profile().save()
user = request.user
user.profile = profile
user.save()
return redirect('users')
else:
print(form.errors)
else:
form = RegisterForm()
# …

Django email notification

I want to ask for guidance on how to do this Django email notification
https://docs.djangoproject.com/en/1.8/topics/email/#send-mail
I have a basic task form and option to assign it to someone, when the form is saved I want to send an email notification to the assigned user.
Job/task models.py
class Job(models.Model):
completed = models.BooleanField(default=False)
task_name = models.CharField(max_length=80, blank=False)
description = models.CharField(max_length=80, blank=False)
is_important = models.BooleanField(default=False)
completion_date = models.DateField(blank=True, null=True)
assign_to = models.ForeignKey(User, blank=True, null=True)
comments = models.TextField(blank=True)
def __unicode__(self):
return self.task_name
Job/task view.py
#login_required
def job(request):
if request.method == 'POST':
form = JobForm(request.POST)
if form.is_valid():
job_record = form.save(commit=False)
job_record = form.save(commit=False)
job_record.user = request.user
job_record.save()
return redirect('jobs:list')
else:
form = JobForm()
return render(request, 'jobs/form.html', {'form': form})
You are nearly there:
#login_required
def job(request):
form = JobForm(request.POST or None)
if form.is_valid():
job_record = form.save(commit=False)
job_record.assign_to = request.user
job_record.save()
send_mail(
subject="subject",
message="message",
from_email="from#myserver.com",
recipient_list=[job_record.assign_to.email]
)
return redirect('jobs:list')
return render(request, 'jobs/form.html', {'form': form})

Categories