how to solve unusual logical error in django - python

So I made this transaction process that will pass with the help of phone number. But the logic is not working properly. sender side is deducting way more numbers that i want to send. for example, if i want to send 100, it's deducting 500 and receiver is not receiving the amount.
can anyone help me with this?
models.py
class extenduser(models.Model):
ID= models.IntegerField(null=True, default=None)
FirstName= models.CharField(max_length= 50)
MiddleName= models.CharField(max_length=50)
LastName= models.CharField(max_length=50)
phone= models.CharField(max_length=20)
user= models.OneToOneField(User, on_delete=models.CASCADE)
class Status (models.Model):
user_name = models.CharField(max_length=150, default=None)
account_number = models.IntegerField()
balance = models.IntegerField()
phone_number= models.CharField(max_length=20,default=None)
class MoneyTransfer(models.Model):
enter_your_user_name = models.CharField(max_length = 150, default = None)
enter_the_destination_account_number = models.IntegerField()
enter_the_destination_phone_number=models.CharField(max_length=20, default=None)
enter_the_amount_to_be_transferred_in_INR = models.IntegerField()
views.py
def randomGen():
# return a 6 digit random number
return int(random.uniform(100000, 999999))
def index(request):
try:
curr_user = Status.objects.get(user_name=request.user) # getting details of current user
except:
# if no details exist (new user), create new details
curr_user = Status()
curr_user.account_number = randomGen() # random account number for every new user
curr_user.balance = 0
curr_user.user_name = request.user
curr_user.phone_number= extenduser.phone
curr_user.save()
return render(request, "epayapp/index.html", {"curr_user": curr_user})
def TransferMoney(request):
if request.method == "POST":
form = forms.MoneyTransferForm(request.POST)
if form.is_valid():
form.save()
curr_user = models.MoneyTransfer.objects.filter(enter_your_user_name=request.user).first()
dest_user_acc_num = curr_user.enter_the_destination_account_number
dest_phone_num= curr_user.enter_the_destination_phone_number
temp = curr_user # NOTE: Delete this instance once money transfer is done
dest_user = models.Status.objects.get(account_number=dest_user_acc_num)
dest_phn= models.Status.objects.get(phone_number= dest_phone_num)
transfer_amount = curr_user.enter_the_amount_to_be_transferred_in_INR
curr_user = models.Status.objects.get(user_name=request.user)
# Now transfer the money!
curr_user.balance = curr_user.balance - transfer_amount
dest_phn.balance = dest_phn.balance + transfer_amount
curr_user.save()
dest_user.save()
# Save the changes before redirecting
temp.delete() # NOTE: Now deleting the instance for future money transactions
return redirect(index)
else:
form = forms.MoneyTransferForm()
return render(request, "epayapp/Transfer_money.html", {"form": form})

Related

How Can I set and Get Django Form Value on Another View

I am working on a Django Ticketing project where I want guest to activate Ticket PIN and then register for the event they bought the ticket for. And I also want them to have login user access and be able to update profile immediately after login.
The application usually start with PIN activation and thereafter guest registration. The issue is that I don't know how to pass the PIN value from the PIN activation view to the guest registration view.
Notice that I have used request.session['pin'] = pin_value to set the PIN as the session variable in the pin activation view and got it using user_pin = request.session.get('pin') in the register guest view but only the Guest.objects.create(guest_name=new_user, pin=user_pin) in the register guest view gets the session variable while the Pin.objects.filter(value=user_pin).update(status='Activated') fails to get the session variable for the registration process to be completed. I have tried using a literal value in the Pin filter and update query and it worked but using the session variable does not.
Below are my models:
class Guest(models.Model):
guest_name = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
pin = models.CharField(max_length=6, default='No Pin', blank=True)
def __str__(self):
return f"{self.guest_name}"
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
surname = models.CharField(max_length=20, null=True)
othernames = models.CharField(max_length=40, null=True)
gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
phone = PhoneNumberField()
image = models.ImageField(default='avatar.jpg', blank=False, null=False, upload_to ='profile_images',
)
def __str__(self):
return f'{self.user.username}-Profile'
class Pin(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
value = models.CharField(max_length=6, default=generate_pin, blank=True)
added = models.DateTimeField(auto_now_add=True, blank=False)
reference = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
status = models.CharField(max_length=30, default='Not Activated')
#Save Reference Number
def save(self, *args, **kwargs):
self.reference == str(uuid.uuid4())
super().save(*args, **kwargs)
def __unicode__(self):
return self.ticket
class Meta:
unique_together = ["ticket", "value"]
def __str__(self):
return f"{self.ticket}"
def get_absolute_url(self):
return reverse("pin-detail", args=[str(self.id)])
My Views code:
def pin_activation(request):
if request.method == "POST":
#Create PIN form
form = PinActivationForm(request.POST)
#Get User Pin Value from Form
pin_value = form['pin'].value()
#Check if the the form has valid data in it
if form.is_valid():
try:
#Get user Pin with the one in the Database
check_pin_status = Pin.objects.get(value=pin_value)
except Pin.DoesNotExist:
messages.error(request, f'{pin_value} Does Not Exist')
return redirect('pin-activation')
else:
#Check PIN status
if check_pin_status:
#Get Event Ticket Date of the PIN
event_date = check_pin_status.ticket.event.date
#Get Current Date
current_date = datetime.now().date()
#Check if Event Date is Passed the Current Date
if event_date < current_date:
messages.error(request, 'Event Has Passed')
return redirect('pin-activation')
else:
#Update the User Pin with a new status of Activated
Pin.objects.filter(value=form['pin'].value()).update(status='Validated')
#Message the User
messages.success(request, 'Pin Validated Successfully')
#Redirect the user to register for seat
return redirect('register-guest')
#Check filter the DB where the PIN status is Validated
request.session['pin'] = pin_value
elif Pin.objects.filter(value=form['pin'].value(), status="Validated"):
messages.error(request, 'Pin Already Validated. Register for Seat')
return redirect('register-guest')
#Check Filter PIN in DB where Status is Activated
elif Pin.objects.filter(value=form['pin'].value(), status="Activated"):
messages.error(request, "Pin Already Activated, Login.")
return redirect('user-login')
else:
messages.error(request, 'Something Went Wrong. Try again')
else:
form = PinActivationForm()
context = {
'form':form,
}
return render(request, 'user/pin_activation.html', context)
def register_guest(request):
#get session variable
user_pin = request.session.get('pin')
form = GuestUserForm(request.POST)
page_title = "Festival Registration"
if request.method == 'POST':
form = GuestUserForm(request.POST)
pin_form = PinActivationForm(request.POST)
if form.is_valid() and pin_form.is_valid():
new_user = form.save()
Guest.objects.create(guest_name=new_user, pin=user_pin)
Pin.objects.filter(value=user_pin).update(status='Activated')
messages.success(request, 'Registered Successfully. Login')
return redirect('user-login')
else:
form = GuestUserForm()
pin_form = PinActivationForm()
context = {
'form':form,
'pin_form':pin_form,
'page_title':page_title,
}
return render(request, 'user/register.html', context)
Someone should please help with the best way of solving this problem. Thanks
you cannot save a quest as a User in this way.
Do something like this.
From youre form get the username.
Then create a new User with that username and create the Guest with that new user.
//simple form --> get it in youre template
class GuestUserForm(forms.Form):
username = forms.CharField()
password=forms.CharField()
//create new user from the form in template
user_guest = form.cleaned_data.get("username")
new_user = User.objects.create_user(username=user_guest)
//create new guest with created user
Guest.objects.create(guest_name=new_user)
//youre view function
def register_guest(request):
if request.method == 'POST':
form = GuestUserForm(request.POST)
if form.is_valid():
user_guest = form.cleaned_data.get("username")
print(user_guest)
new_user = User.objects.create_user(username=user_guest)
Guest.objects.create(guest_name=new_user)
form = GuestUserForm()
return render(request, "index.html",{"form":form})

Django is not populating correctly an specific form using a Queryset

I have created two models Leads and Deals, and I have coded some logic such that if you click a button the Lead becomes a Deal, so what I want it is that a new form is presented to the user but that form already contains the information from the Leads model.
#login_required
def close_lead(request):
if request.method == 'POST':
deal_form = DealForm(request.POST)
if deal_form.is_valid():
deal_form.save()
messages.success(request, 'You have successfully updated the status from open to Close')
id = request.GET.get('project_id', '')
obj = Leads.objects.get(project_id=id)
obj.status = "Closed"
obj.save(update_fields=['status'])
return HttpResponseRedirect(reverse('dashboard'))
else:
messages.error(request, 'Error updating your Form')
else:
id = request.GET.get('project_id', '')
obj = get_object_or_404(Leads, project_id=id)
print(obj.expected_revenue)
form = NewDealForm(request.POST or None, instance=obj)
return render(request,
"account/close_lead.html",
{'form':form})
I have done some debug and printed to the console the queryset and the information is fine, so the queryset is no the problem, the problem is that the NewForm doesn't prepopulate the new values.
models.py (only 2 models shown)
class Leads(models.Model):
CHOICES = (
('Illumination Studies','Illumination Studies'),
('Training','Training'),
('Survey Design','Survey Design'),
('Software License','Software License')
)
STATUS = (('Open','Open'),
('Closed','Closed'),
('Canceled', 'Canceled')
)
project_id = models.BigAutoField(primary_key=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
agent = models.ForeignKey(Profile, on_delete=models.CASCADE, default="agent")
created_at = models.DateTimeField(auto_now_add=True)
point_of_contact = models.ForeignKey(Client, on_delete=models.CASCADE)
expected_revenue = MoneyField(max_digits=14, decimal_places=2, default_currency='USD')
expected_licenses = models.IntegerField(blank=True)
country = CountryField(blank_label='(select country)')
status = models.CharField(max_length=10,choices=STATUS)
estimated_closing_date = models.DateField(blank=True)
services = models.CharField(max_length=20,choices=CHOICES)
def __str__(self):
return f'{self.company}'
class Deal(models.Model):
project_id = models.ForeignKey(Leads, on_delete=models.CASCADE, default='id')
agent = models.ForeignKey(Profile, on_delete=models.CASCADE, default="agent")
service = models.ForeignKey(Leads, on_delete=models.CASCADE, related_name='service')
closing_date = models.DateField(auto_now_add=True)
client = models.ForeignKey(Client, on_delete=models.CASCADE,default='client')
licenses = models.ForeignKey(Leads,on_delete=models.CASCADE, related_name='licenses')
revenue = MoneyField(max_digits=14, decimal_places=2, default_currency='USD')
comments = models.TextField(blank=True,null=True)
Now, it could be that I have to inherit from a different form?
forms.py (only NewDealForm)
class NewDealForm(forms.ModelForm):
class Meta:
model = Deal
fields = ['agent','client','project_id','service', 'licenses','revenue', 'comments']
Obviously, worst-case scenario is to create a dictionary to extract the data from the queryset and then pass it to the form, but I'm sure Django has a more elegant way to handle this process.
Well, I guess sometimes Stack Overflow pushes you to solve your own issues, this is the solution.
Essentially, the initial=queryset value was not initializing the form mainly because I have very specific relationships in my model, so what I did is to create a dictionary (key:value) with the form field as key, and my queryset from my model as the value, the code is as below:
'''
def close_lead(request):
if request.method == 'POST':
deal_form = DealForm(request.POST)
if deal_form.is_valid():
deal_form.save()
messages.success(request, 'You have successfully updated the status from open to Close')
id = request.GET.get('project_id', '')
obj = Leads.objects.get(project_id=id)
obj.status = "Closed"
obj.save(update_fields=['status'])
return HttpResponseRedirect(reverse('dashboard'))
else:
messages.error(request, 'Error updating your Form')
else:
id = request.GET.get('project_id', '')
obj = get_object_or_404(Leads, project_id=id)
m = obj.__dict__
keys = Leads.objects.get(project_id=m['project_id'])
form_dict = {'project_id':keys.project_id,
'agent':keys.agent,
'client':keys.point_of_contact,
'company':keys.company,
'service':keys.services
}
form = NewDealForm(request.POST or None,initial = form_dict)
return render(request,
"account/close_lead.html",
{'form':form})
'''
As you can see, I create an object dictionary because the forms are different, so they share some common values not all, and then I simply adapt the dictionary, nice and easy, but I somehow expected that Django somehow finds relationships by name?, but maybe the batteries are not included for this.

Cannot assign "'7'": "Appointment.your_service" must be a "Service" instance

I'm working on a project "Beauty Parlour Management System" and I got this error (Cannot assign "'7'": "Appointment.your_service" must be a "Service" instance.) anyone here can help me, please.
When I am filling a book appointment form then I got this error.
models.py
class Service(models.Model):
name = models.CharField(max_length=50)
price = models.IntegerField(default=0)
image = models.ImageField(upload_to='uploads/productImg')
class Appointment(models.Model):
your_name = models.CharField(max_length=100)
your_phone = models.CharField(max_length=10)
your_email = models.EmailField(max_length=200)
your_service = models.ForeignKey('Service', on_delete=models.CASCADE, default=1)
your_date = models.DateField()
views.py
def appointments(request):
if request.method == 'GET':
return render(request, 'core/bookappointment.html')
else:
your_name = request.POST.get('your-name')
your_phone = request.POST.get('your-phone')
your_email = request.POST.get('your-email')
your_service = request.POST.get('your-service')
your_date = request.POST.get('your-date')
details = Appointment(
your_name = your_name,
your_phone = your_phone,
your_email = your_email,
your_service = your_service,
your_date = your_date)
details.save()
return render(request, 'core/appointments.html')
You create this by assigining the method to your_service_id field, if you work with your_service, it should be a Service object:
details = Appointment.objects.create(
your_name=your_name,
your_phone=your_phone,
your_email=your_email,
your_service_id=your_service,
your_date=your_date
)
That being said, it is usually better to validate, clean, and save the data with a ModelForm, not manually.
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
def appointments(request,pk):
record = get_object_or_404(Service,pk=pk)
if request.method == 'POST':
form = appointmentsForm(request.POST,request.FILES)
if form.is_valid():
appointment= form.save(commit=False)
appointment.your_service = record
appointment.save()
return render(request, 'core/bookappointment.html')
else:
return render(request, 'core/appointments.html')

Manage ModelManyToMany request in views.py

I have a ModelManyToMany selector in my html.
(I can't post images so, here is the url to image: https://i.stack.imgur.com/HDhde.png)
I want to catch the user's selections with my POST method in my views.py
views.py
class userPageView(TemplateView):
template_name = 'user.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['edit_profile_form'] = EditProfileForm(prefix='edit')
return context
def post(self, request, *args, **kwargs):
edit_name = request.POST.get('edit-name')
edit_two_factors_auth = request.POST.get('edit-two_factors_auth')
edit_coins = request.POST.get('edit-coins')
if request.method == "POST":
if 'profileButton' in request.POST:
if edit_name and (edit_name != request.user.name):
request.user.name = edit_name
request.user.save()
print(edit_coins)
return render(request, 'user.html')
models.py
class Usuario(AbstractUser):
name = models.CharField(max_length=12, help_text="The name must be between 2 and 12 characters")
email = models.EmailField(max_length=60, unique=True, help_text="The email must be between 5 and 30 characters")
password = models.CharField(max_length=78)
change_password_code = models.CharField(blank=True,max_length=15)
activated = models.BooleanField(default=False)
activated_code = models.CharField(default="",max_length=15)
ip = models.CharField(blank=True,max_length=15)
last_login = models.DateField(default=now)
wallets = models.ManyToManyField(Wallet)
coins = models.ManyToManyField(Coin)
avatar = models.CharField(blank=True,default="bitcoin.png",max_length=15)
delete_code = models.CharField(default="",max_length=9,blank=True)
two_factors_auth = models.BooleanField(default=False)
two_factors_auth_code = models.CharField(default="",max_length=12,blank=True)
fingerprint = models.CharField(max_length=64,blank=True)
The print in my views.py only returns me the last selection, but not all the set of choices that the user has done.
I want to save all coins selections by the users in his coins field
you must change this line
edit_coins = request.POST.get('edit-coins')
to
edit_coins = request.POST.getlist('edit-coins')
and its works. after that edit_conis is a list contain all items user selected.

Poll application with indefinite options, prevent voting from off the options displayed

I'm working on a django voting system where you get displayed a small random amount of options from a pool of candidates, and the way i submit the votes is by using the ID's of the options, but i can't think of a way to keep people from just changing the source code and submitting votes on the same option over and over, the options get displayed on the view and template like this:
return render(request, '/vote.html', {'p': po, 'opts':
opts.order_by('?')[:3]
{%for v in opts%}
<div class='votebox' name='{{v.id}}' onclick='vote()'></div>
{%endfor%}
What's a code efficient way to check if the user voted on an option that was displayed to them?
the voting option model is this
class Submission(models.Model):
def __str__(self):
return self.title
title = models.CharField(max_length=20)
signature = models.CharField(max_length=20)
sub_date = models.DateField()
poll = models.ForeignKey('Poll', on_delete=models.CASCADE)
vote_count = models.IntegerField(null=True)
img = models.ImageField(upload_to='MEDIA_ROOT')
repcount = models.IntegerField()
the Poll model is:
class Poll(models.Model):
title = models.CharField(max_length=20)
author = models.ForeignKey(User, on_delete=models.CASCADE)
start_date = models.DateField()
end_date=models.DateField()
and the view where it goes is this
def poll(request, id):
if request.method == "GET":
po = poll.objects.get(id=id)
daysleft = poll.end_date - datetime.date.today()
opts = po.submission_set.all()
return render(request, '/vote.html', {'p': po, 'opts' : opts, 'daysl':daysleft}
elif request.method == "POST":
voted = request.POST.get('voteval', False)
sub = Submission.objects.get(id=voted)
sub.vote_count += 1
sub.save()
I would add an intermediary model between User and Submission
class Vote(models.Model):
user = models.ForeignKey(User)
submission = models.ForeignKey(Submission)
class Meta:
unique_together = (
('user', 'submission'),
)
Now when handling the POST part of the view, you can check if the user has voted on this submission before and create a new Vote object if he hasn't
elif request.method == "POST":
voted = request.POST.get('voteval', False)
sub = Submission.objects.get(id=voted)
user = request.user
try:
vote = Vote.objects.get(user=user, submission=sub)
# warn user that he's voted for this submission
except Vote.DoesNotExist:
vote = Vote.objects.create(user=user, submission=sub)
sub.vote_count += 1
sub.save()

Categories