Django AttributeError at /company-registration/ - python

I have a User model, an ApplicantProfile model, and a CompanyProfielModel. A user can be of two types, an applicant or a company.
models.py
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
date_joined = models.DateTimeField(auto_now_add=True)
is_applicant = models.BooleanField(default=False)
is_company = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
objects = MyUserManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
class ApplicantProfile(models.Model):
GENDER_MALE = 0
GENDER_FEMALE = 1
GENDER_CHOICES = [(GENDER_MALE, 'Male'), (GENDER_FEMALE, 'Female')]
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
image = models.ImageField(upload_to=image_directory_path, storage=image_storage, null=True, blank=True)
bio = models.TextField(max_length=500, null=True, blank=True)
address = models.TextField(max_length=200, null=True, blank=True)
birth_date = models.DateField(null=True, blank=True)
phone = PhoneNumberField(null=True, blank=True)
website = models.URLField(max_length=255, null=True, blank=True)
gender = models.IntegerField(choices=GENDER_CHOICES, null=True, blank=True)
interest = models.TextField(max_length=255, null=True, blank=True)
linkedin = models.CharField(max_length=255, null=True, blank=True)
github = models.CharField(max_length=255, null=True, blank=True)
twitter = models.CharField(max_length=255, null=True, blank=True)
facebook = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
return self.user.name
class CompanyProfile(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
image = models.ImageField(upload_to=image_directory_path, storage=image_storage, null=True, blank=True)
about = models.TextField(max_length=500, null=True, blank=True)
location = models.CharField(max_length=100, null=True, blank=True)
start_date = models.DateField(null=True, blank=True)
website = models.URLField(max_length=255, null=True, blank=True)
logo = models.ImageField(upload_to=image_directory_path, storage=image_storage, null=True, blank=True)
def __str__(self):
return self.user.name
I have two URLs to create two different types of users. I can create applicants automatically right after a user registers from the applicant registration url, but I can't create companies from the company registration url.
views.py
def applicant_register(request):
if request.method == 'POST':
form = ApplicantRegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password1')
user = authenticate(email=email, password=raw_password)
ApplicantProfile.objects.create(user=user)
messages.success(request, "Account created successfully.")
return redirect('applicant-feed')
form = ApplicantRegistrationForm()
context = {
"form": form
}
return render(request, 'user/applicant/applicant-register.html', context)
def company_register(request):
if request.method == 'POST':
form = CompanyRegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password1')
user = authenticate(email=email, password=raw_password)
CompanyProfile.objects.create(user=user) # This line gives the error
messages.success(request, "Account created successfully.")
return redirect('company-feed')
form = CompanyRegistrationForm()
context = {
"form": form
}
return render(request, 'user/company/company-register.html', context)
Any help is appreciated.
Getting this error in the browser

According to error, looks like CompanyProfile is not a model class but something else. Is there a chance that you redefine it in views.py? Probably you also define a view with this name?

you don't need to use the form because you can create an account directly to any model like this function
def company_register(request):
if request.method == 'POST':
user = request.POST['user']
image = request.FILES['image']
about = request.POST['about']
location = request.POST['location']
start_date = request.POST['start_date']
website = request.POST['website']
logo = request.FILES['logo']
profile = CompanyProfile.objects.create(user=user, image=image, about=about, location=location, start_date=start_date, website=website, logo=logo)
profile.save()
return Response('Done')
else:
return Response('POST method only accepted')

Related

Initial data not working if I hide some one-to-many fields in django

I want to prefill some one to many fields and also hide these field because I want to avoid a scenario where a user can see all the records related to the fields. The problem I'm facing is when I use 'all' on the form fields I the initial data dictionary is working well, but if I try to use a list of the fields I want displayed, the initial data is not getting passed into the form.
Here is my models.py:
class Agent(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = OneToOneField(User, null=True, blank=True, on_delete=models.SET_NULL)
first_name = models.CharField(max_length=15, null=True, blank=True,)
surname = models.CharField(max_length=15, null=True, blank=True,)
provcoord = models.ForeignKey(Provcoord, null=True, blank=True, on_delete=SET_NULL)
regcoord = models.ForeignKey(Regcoord, null=True, blank=False, on_delete=SET_NULL)
region = models.CharField(max_length=15, null=False, blank=True, choices=REGION)
province = models.CharField(max_length=15, null=False, blank=False, choices=PROVINCE)
id_no = id_no = models.CharField(max_length=10, null=False, blank=False, unique=True,)
agent_no = models.CharField(default="Not Assigned", max_length=20, null=False, blank=False)
address = models.TextField(null=False, blank=False)
gender = models.CharField(max_length=20, null=False, blank=False, choices=GENDER)
profile_pic = models.ImageField(upload_to="assets", default="default.png")
is_blacklisted = models.BooleanField(default=False)
reason_for_blacklist = models.TextField(max_length=500, null=True, blank=True)
registered_at = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
return reverse("agent", kwargs={'str' :str.id})
def __str__(self):
return self.user.username
class Adult(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
agent = models.ForeignKey(Agent, null=True, blank=True, on_delete=SET_NULL)
regcoord = models.ForeignKey(Regcoord, null=True, blank=True, on_delete=SET_NULL)
provcoord = models.ForeignKey(Provcoord, null=True, blank=True, on_delete=SET_NULL)
surname = models.CharField(max_length=150, null=False, blank=False)
first_name = models.CharField(max_length=150, null=False, blank=False)
other_name = models.CharField(max_length=150, null=True, blank=True)
address = models.CharField(max_length=200, null=True, blank=True)
region = models.CharField(max_length=15, null=True, blank=True,choices=PROVINCE)
dob = models.CharField(max_length=10, null=False, blank=False)
gender = models.CharField(max_length=20, null=False, blank=False, choices=GENDER)
id_no = models.CharField(max_length=12, null=False, blank=False, unique=True)
receipt_no = models.CharField(max_length=10, default="Not Receipted", null=True,
blank=True)
phone_no = models.CharField(max_length=20, null=False, blank=False,)
marital_status = models.CharField(max_length=20, null=False, blank=False, choices=MARITAL_STATUS)
views.py:
def add_parent(request,):
agent = request.user.agent
regcoord = request.user.agent.regcoord
provcoord = request.user.agent.provcoord
region = request.user.agent.region
province = request.user.agent.province
form = ParentForm(initial={
'agent' :agent,
'regcoord' :regcoord,
'provcoord' :provcoord,
'region' :region,
'province' :province
})
if request.method == 'POST':
form = ParentForm(request.POST, request.FILES,)
if form.is_valid():
form.save()
return redirect('/')
context = {'form' :form}
return render(request, 'kyc/add_adult.html', context)
forms.py:
class ParentForm(ModelForm):
class Meta:
model = Adult
fields = ['surname',
'first_name',
'other_name',
'address',
'dob',
'gender',
'id_no',
'receipt_no',
'phone_no',
'image'
]
Please Help on how I can get around this issue.
Here is an approach I suggest (not tested though):
from django import forms
class ParentForm(ModelForm):
agent = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
regcoord = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
provcoord = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
region = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
province = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(ParentForm, self).__init__(*args, **kwargs)
self.fields['agent'].initial = self.user.agent
self.fields['regcoord'].initial = self.user.regcoord
self.fields['provcoord'].initial = self.user.provcoord
self.fields['region'].initial = self.user.region
self.fields['province'].initial = self.user.province
class Meta:
model = Adult
fields = ['surname',
'first_name',
'other_name',
'address',
'dob',
'gender',
'id_no',
'receipt_no',
'phone_no',
'image'
]
Notes how I referenced the 5 fields (agent, regcoord, provcoord, region, province) as extra fields by declaring them as simple CharFields. So they are no longer rendered from the model as dropdown lists. Then in the method __init__ I define the initial values ​​for each of the fields.
Your function add_parent should become:
def add_parent(request,):
form = ParentForm(user=request.user)
if request.method == 'POST':
form = ParentForm(request.POST, request.FILES,)
if form.is_valid():
form.save()
return redirect('/')
context = {'form' :form}
return render(request, 'kyc/add_adult.html', context)
Edit
Here is another alternative:
def add_parent(request,):
data = {'agent': request.user.agent, 'regcoord': request.user.regcoord, 'provcoord': request.user.provcoord, 'region': request.user.region, 'province': request.user.province}
form = ParentForm(initial=data)
if request.method == 'POST':
form = ParentForm(request.POST, request.FILES,)
if form.is_valid():
form.save()
return redirect('/')
context = {'form' :form}
return render(request, 'kyc/add_adult.html', context)
In the function add_parent, I pass the initial values ​​in the form of a dictionary (data), to the variable initial.
Then you need to remove the __init__ method from your form. Django will take care of rendering the form with the initial values ​​in the corresponding fields.

How Can I Integrate Flutterwave Paymwnt Gate Way with Django

I am working on a Django Project where I want to collect payment in Dollars from Applicants on the portal, and I don't know how to go about it. Though I have been following an online tutorial that shows how to do it but the result I am having is different with the recent error which says 'module' object is not callable.
Remember that I have tested my configured environment and also imported it into my views on top of the page.
Profile model code:
class Profile(models.Model):
applicant = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
surname = models.CharField(max_length=10, null=True)
othernames = models.CharField(max_length=30, null=True)
gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
nation = models.CharField(max_length=255, choices=NATION, blank=True, null=True)
state = models.CharField(max_length=20, null=True)
address = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=16, null=True)
image = models.ImageField(default='avatar.jpg', upload_to ='profile_images')
def __str__(self):
return f'{self.applicant.username}-Profile'
Education/Referee Model code:
class Education(models.Model):
applicant = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
qualification = models.CharField(max_length=60, choices=INSTITUTE, default=None, null=True)
instition = models.CharField(max_length=40, null=True)
reasons = models.CharField(max_length=100, null=True)
matnumber = models.CharField(max_length=255, null=True)
reference = models.CharField(max_length=100, null=True)
refphone = models.CharField(max_length=100, null=True)
last_updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return f'{self.applicant}-Education'
Submitted Model code:
class Submitted(models.Model):
applicant = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
application = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
confirm = models.BooleanField()
approved = models.CharField(max_length=20, null=True)
date = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
self.application == str(uuid.uuid4())
super().save(*args, **kwargs)
def __unicode__(self):
return self.applicant
def __str__(self):
return f'Application Number: {self.application}-{self.applicant}'
Scholarship Model code:
class Scholarship(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null = True)
name = models.CharField(max_length=100, null = True)
description = models.CharField(max_length=200, null = True)
category = models.CharField(max_length=60, choices=INSTITUTE, default=None, null=True)
amount = models.FloatField()
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'WASU Scholarship: {self.name}-{self.name}'
My View for printing slip:
def AppSlip(request):
check_submited = Submitted.objects.get(applicant=request.user)
check_education = Education.objects.get(applicant = request.user)
candidate_edu = check_education.qualification
scholarship = Scholarship.objects.get(category=candidate_edu)
context = {
'candidate_edu':candidate_edu,
'scholarship':scholarship,
}
return render(request, 'user/slip.html', context)
My view for applicant to fill form for payment which I want their Profile captured automatically in the form:
def scholarship_detail(request, pk):
data = Scholarship.objects.get(id=pk)
if request.method=='POST':
form = PaymentForm(request.POST)
if form.is_valid():
user = Profile.objects.get(applicant=request.user)
name= user.surname
email = form.cleaned_data['email']
amount = form.cleaned_data['amount']
phone = form.cleaned_data['phone']
context = {'applicant':name, 'email':email, 'amount':amount, 'phone':phone}
return process_payment(request, context)
else:
form = PaymentForm()
ctx={
'form':form,
'product':data,
}
return render(request, 'user/scholarship.html', ctx)
My form code for Payment: How can query logged in user profile and fill into name, email, phone, amount from Scholarship Model into amount form filled.
class PaymentForm(forms.Form):
name = forms.CharField(label='Your name', max_length=100)
email = forms.EmailField()
phone=forms.CharField(max_length=15)
amount = forms.FloatField()
View code for processing Payment (Where I am suspecting the error). Though I have configured my env using django-dotenv with the Flutterwave Secret Key in it.
#login_required(login_url='user-login')
def process_payment(request, newContext={}):
auth_token= dotenv('SECRET_KEY')
hed = {'Authorization': 'Bearer ' + auth_token}
data = {
"tx_ref":''+str(math.floor(1000000 + random.random()*9000000)),
"amount":amount,
"currency":"KES",
"redirect_url":"http://localhost:8000/callback",
"payment_options":"card",
"meta":{
"consumer_id":23,
"consumer_mac":"92a3-912ba-1192a"
},
"customer":{
"email":email,
"phonenumber":phone,
"name":name
},
"customizations":{
"title":"WASU Scholarship 2022",
"description":"Best store in town",
"logo":"https://getbootstrap.com/docs/4.0/assets/brand/bootstrap-solid.svg"
}
}
url = ' https://api.flutterwave.com/v3/payments'
response = requests.post(url, json=data, headers=hed)
response=response.json()
link=response['data']['link']
return link
My payment Response View:
#require_http_methods(['GET', 'POST'])
def payment_response(request):
status=request.GET.get('status', None)
tx_ref=request.GET.get('tx_ref', None)
print(status)
print(tx_ref)
return HttpResponse('Finished')
Anticipating your prompt answers. Thanks

Populate a Django form field with data from a model

I'm have been struggling on this for 2 days, really. I want to populate Timesheet form field from Employees model as a select field / dropdown list.
Here are my files and I tried so far.
MODEL.PY
class Employees(models.Model):
# MONTHLY = 'MONTHLY'
# SEMIMONTHLY = 'SEMIMONTHLY'
# BIWKEEKLY = 'BIWKEEKLY'
# WEEKLY = 'WEEKLY'
# DAILY = 'DAILY'
PAY_PERIODS = [
('Monthly', 'Monthly'),
('Bi-weekly', 'Bi-weekly'),
('Weekly', 'Weekly'),
('Daily', 'Daily'),
]
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
is_active = models.BooleanField(default=True, verbose_name='Employee is actives')
first_name = models.CharField(max_length=50, verbose_name='First Name.', null=True, blank=False)
middle_name = models.CharField(max_length=50, verbose_name='Middle Name or Initials.', null=True, blank=True)
last_name = models.CharField(max_length=50, verbose_name='Last Name.', null=True, blank=False)
full_name = models.CharField(max_length=50, null=True, blank=True)
phone = PhoneField(blank=True, null=True)
email = models.EmailField(max_length=150, blank=True, null=True)
state = USStateField(null=True, blank=True)
street_address = models.CharField(max_length=150, blank=True, null=True, verbose_name='Street Address.')
zip_code = models.CharField(max_length=50, blank=True, null=True, verbose_name='Zip Code.')
hourly_rate = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
pay_frequency = models.CharField(max_length=100, choices=PAY_PERIODS, blank=True)
hire_date = models.TimeField(auto_now_add=True)
def __str__(self):
return self.full_name
def save( self, *args, **kwargs ):
self.full_name = f'{self.first_name} {self.middle_name} {self.last_name}'
super().save( *args, **kwargs )
class Timesheet(models.Model):
"""A timesheet is used to collet the clock-ins/outs for a particular day
"""
employer = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
full_name = models.ForeignKey(Employees, on_delete=models.CASCADE, null=True, blank=False, verbose_name='Select YOUR Name')
start_date = models.DateField(auto_now_add=True, null=True)
end_date = models.DateField(null=True, blank=False)
time_worked = models.DateField(null=True, blank=False)
def __str__(self):
return self.full_name
VIEWS.PY # I tried both function and class based views
class TimesheetView(CreateView):
model = Timesheet
fields = ('full_name', )
# form_class = TimesheetFrom
# queryset = Employees.objects.filter()
# print(queryset)
template_name = 'users/timesheet.html'
success_url = reverse_lazy('timesheet')
#login_required
def timesheet_view(request):
if request.method == 'POST':
form = TimesheetFrom(request.POST)
if form.is_valid():
emp = form.save(commit=False)
emp.user_id = request.user.pk
emp.save()
return redirect('dashboard')
else:
form = TimesheetFrom()
context = {
'form': TimesheetFrom(),
}
return render(request, 'users/timesheet.html', context)
FORM.PY
class TimesheetFrom(forms.Form):
class Meta:
model = Timesheet
fields = '__all__'
exclude = ('employer', )
#This is the current state of the form but I did tried many approaches.
I did search extensively here (Stackoverflow) but no use case for me. Any help will be greatly appreciated with a cup of coffee.

How fetch username of staff user in django forms

I am using a custom User model. And I have another Customer model. I want the user field will only show the staff user no other type of user in the field will show in the registration form. In my case, it is showing all types of users whether it is staff or customer or a service user.
Models.py
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=254, unique=True)
name = models.CharField(max_length=254, null=True)
email = models.EmailField(max_length=254, null=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_Customer = models.BooleanField(default=False)
is_Service_Provider = models.BooleanField(default=False)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'username'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def get_absolute_url(self):
return "/users/%i/" % self.pk
def get_username(self):
return self.username
class Customer(models.Model):
user = models.OneToOneField('accounts.User', on_delete=models.SET_NULL, null=True)
email = models.EmailField(max_length=254, null=False)
date_Of_Birth = models.DateField(null=False)
country = models.ForeignKey('accounts.Country', null=True, on_delete=models.SET_NULL, related_name='Country')
state = models.ForeignKey('accounts.State', null=True, on_delete=models.SET_NULL, related_name='State')
city = models.ForeignKey('accounts.City', null=True, on_delete=models.SET_NULL, related_name='city')
address = models.CharField(max_length=254, null=False)
refernce_by_person_name = models.CharField(max_length=254, null=True)
refernce_by_person_contact_no = models.IntegerField(null=True)
phone_no = models.IntegerField(null=False)
alternate_no = models.IntegerField(null=False)
hobbies = models.CharField(max_length=254)
def __str__(self):
return self.user.username
views.py
def form(request):
forms = CustomerRegistrationForm()
if request.method == "POST":
forms = CustomerRegistrationForm(request.POST)
if forms.is_valid():
forms.save()
return redirect('/customer/show')
context = {
'forms' : forms,
}
return render(request,'customer/form.html', context)
forms.py
class CustomerRegistrationForm(forms.ModelForm):
class Meta:
model = Customer
fields = '__all__'
You can filter the staff users in the form like this.
class CustomerRegistrationForm(forms.ModelForm):
user = forms.ModelChoiceField(queryset=User.objects.filter(is_staff=True))
class Meta:
model = Customer
fields = ['user','email','date_of_birth',...]

form object has no attribute 'email' in django

I have a registration form made of 2 forms, from which email field gets saved in both User and Student models. Now, I made an update account info view. Problem is, I want that email will get updated the in both models. But I get error:
'StudentEditForm' object has no attribute 'email'
Here is my code:
class StudentEditForm(forms.ModelForm):
email = forms.EmailField(required=False)
name = forms.CharField(max_length=30)
surname = forms.CharField(max_length=50)
photo = forms.ImageField(required=False)
phone = forms.CharField(max_length=15, required=False)
class Meta:
model = Student
fields = ('email', 'name', 'surname', 'phone', 'photo')
class User(AbstractUser):
pass
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
name = models.CharField(max_length=30, null=True, blank=True, default=None)
surname = models.CharField(max_length=50, null=True, blank=True, default=None)
email = models.EmailField(unique=True, null=True, blank=True, default=None)
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')],
null=True, blank=True, default=None)
photo = models.ImageField(upload_to='students_images', null=True, blank=True, default=None)
phone = models.CharField(max_length=15, null=True, blank=True, default=None)
def __str__(self):
return self.surname
User.student = property(lambda p: Student.objects.get_or_create(user=p)[0])
def profile_edit(request):
user = request.user
student = request.user.student
if request.method != 'POST':
form = StudentEditForm(instance=student)
else:
form = StudentEditForm(request.POST, instance=student)
user.email = form.email
form.save()
return render(request, 'index.html')
context = {
"form": form,
}
return render(request, "registration/profile_edit.html", context)
Again, I need that I will be able to update the email fields. And the email will get saved in User email but also I want it saved to Student email.
call form.is_valid() and then use form.cleaned_data['email'], see https://docs.djangoproject.com/en/1.11/topics/forms/
I had to add
form.is_valid()
and
user.email = form.cleaned_data['email']
but also to add user.save() which solved this issue.

Categories