Django save() method not inserting data to database - python

I am facing a strange problem while inserting data to database using Django models.save() method. I have been using save() method in some other apps of same project. In this app named payments, I am getting postrequest from a payment gateway and I am inserting data into database on success
Structure of my payment model is given below:
Payment Model
from django.db import models
# Create your models here.
class payments(models.Model):
transactionId = models.CharField(max_length=50,default=None)
uniqueOrderId = models.CharField(max_length=50,default=None)
userId = models.CharField(max_length=30,default=None)
productId = models.CharField(max_length=30,default=None)
amount = models.CharField(max_length=30,default=None)
date = models.CharField(max_length=30,default=None)
Views.py
from django.shortcuts import render, render_to_response
from django.http import HttpResponse,HttpResponseRedirect
from django.template.loader import get_template
from django.template import Context, Template,RequestContext
import datetime
import hashlib
from random import randint
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.core.context_processors import csrf
from django.contrib.auth.models import User
from questions.models import questions as questionData
from payments.models import payments
def success(request):
c = {}
c.update(csrf(request))
status=request.POST["status"]
firstname=request.POST["firstname"]
amount=request.POST["amount"]
txnid=request.POST["txnid"]
posted_hash=request.POST["hash"]
key=request.POST["key"]
productinfo=request.POST["productinfo"]
email=request.POST["email"]
uniqueOrder = request.POST["paymentGatewayOrderID"]
useridReturn = request.POST["udf1"]
productIdReturn = request.POST["udf2"]
salt="mysecretsalt"
try:
additionalCharges=request.POST["additionalCharges"]
retHashSeq=additionalCharges+'|'+salt+'|'+status+'|||||||||||'+email+'|'+firstname+'|'+productinfo+'|'+amount+'|'+txnid+'|'+key
except Exception:
retHashSeq = salt+'|'+status+'|||||||||||'+email+'|'+firstname+'|'+productinfo+'|'+amount+'|'+txnid+'|'+key
hashh=hashlib.sha512(retHashSeq).hexdigest().lower()
if(hashh !=posted_hash):
print "Invalid Transaction. Please try again"
else:
paymentDataInsert = payments(transactionId=txnid,userId=useridReturn,productId=productIdReturn,amount=amount,uniqueOrderId=uniqueOrder,date="today")
paymentDataInsert.save()
print "Thank You. Your order status is ", status
print "Your Transaction ID for this transaction is ",txnid
print "We have received a payment of Rs. ", amount ,". Your order will soon be shipped."
return render_to_response('success.html',RequestContext(request,{"txnid":txnid,"status":status,"amount":amount,"useridReturn":useridReturn,"uniqueOrder":uniqueOrder,"productIdReturn":productIdReturn}))
Payment is processing correctly and all the data correctly rendered on the success.html template.
But data is not inserted into table even though I correctly called
paymentDataInsert = payments(transactionId=txnid,userId=useridReturn,productId=productIdReturn,amount=amount,uniqueOrderId=uniqueOrder,date="today")
paymentDataInsert.save()
Strange thing is, it is not showing any error message. I tried my best to solve the problem, but no success.
Edit 1
I tried paymentDataInsert.save() from another function in a different view with a default value for the entries. Then it worked. It seems like the problem is only for that specific function.

Related

What is the best, cleanest and shortest way to check if a given value is valid URL when working with models?

I rather want to use Django's built-in functionalities as much as possible and avoid implementing stuff myself as much as possible!
Why doesn't the following code issue exceptions when given a non-URL value?
models.py:
from django.core.validators import URLValidator
from django.db import models
class Snapshot(models.Model):
url = models.URLField(validators=[URLValidator])
views.py:
from django.http import HttpResponse
from .models import Snapshot
def index(request):
a = Snapshot(url='gott ist tot')
a.save()
Because this validator is run when you use a django form.
More information about validators on the doc : https://docs.djangoproject.com/en/4.1/ref/validators/
if you do a form :
from django import forms
from .models import Snapshot
class SnshotForm(forms.ModelForm):
class Meta:
model = Snapshot
fields = ('url', )
and your views.py :
from django.http import HttpResponse
from .forms import SnapshotForm
def index(request):
a = SnapshotForm(data={'url': 'gott ist tot'})
if a .is_valid()
a.save()
else:
print(a.errors)
Your validator will be run and you will see the errors form message
Without using form, you can call manually validator in your view or in the save method:
# in views
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
def index(request):
url_validator = URLValidator()
url = 'gott ist tot'
is_valid_url = False
try:
url_validator(url)
except ValidationError:
pass
if is_valid_url:
a = Snapshot(url=url)
a.save()
else:
print(a.errors)
Be careful ! I do not recommanded to bypass the validator with forms, i think it is the better way for maximizing usage of django builtins funtions

Stripe subscription cancel: KeyError 'HTTP_STRIPE_SIGNATURE'

I'm trying to configure Django Stripe Subscriptions for WebApp.
I want to let Subscribed users cancel the subscription themselves.
The code below is to delete user's information from StripeAPI and Django StripeCustomer model.
Here is view.py
import stripe
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http.response import JsonResponse, HttpResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import get_user_model
from subscriptions.models import StripeCustomer
#login_required
#csrf_exempt
def cancel_subscription(request):
if request.user.is_authenticated:
endpoint_secret = settings.STRIPE_ENDPOINT_SECRET
payload = request.body
event = None
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
session = event['data']['object']
stripe_customer = StripeCustomer.objects.get(user=request.user)
stripe.api_key = settings.STRIPE_SECRET_KEY
sub_id = stripe.Subscription.retrieve(stripe_customer.stripeSubscriptionId)
client_reference_id = session.get('client_reference_id')
user = get_user_model().objects.get(id=client_reference_id)
try:
#delete from stripeapi
stripe.Subscription.delete(sub_id)
#delete from StripeCustomer model
StripeCustomer.objects.delete(
user=user,
stripeCustomerId=stripe_customer_id,
stripeSubscriptionId=stripe_subscription_id,
)
print(user.username + ' unsubscribed.')
except Exception as e:
import traceback
traceback.print_exc()
return JsonResponse({'error': (e.args[0])}, status =403)
return render(request, 'home.html')
When I excecute the code error occuerd at
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
The error message is below
Exception Type: keyError
Exception Value: 'HTTP_STRIPE_SIGNATURE'
I don't understand why the error occurs at request.META['HTTP_STRIPE_SIGNATURE'],because other part of this view can execute this code.
I just mentioned the above settings in this question but still if more code is required then tell me I'll update my question with that information. Thank you
I think you're mixing up a webhook handler and a regular POST request route as part of your application here. You either need one or the other, and I suspect you don't need the webhook stuff at all given what you're trying to to.

Finding if lastname exists in database

I'm trying to write a simple IF statement on checking if a lastname in a database exists before a user hits the submit button to create a new record. Here is my code so far, I'm new to Django and Python so the help is appreciated.
I made a variable called lastname, the thought process here is when the user hits submit, it checks the database first before the commit to warn them with a popup if the lastname exists to prevent duplicate records. It would actually be really cool to have it when a person exits the field for it to run the script before they finish filling out the form to save time.
#views.py
from .models import StudentCheck
from django.shortcuts import render
from django.http import HttpResponse, Http404, HttpResponseRedirect
from forms.forms import NewStudentForm
def NewStudentFormCheckList (request):
if request.method == 'POST':
form = NewStudentForm(request.POST)
lastname = StudentCheck.lastname
if form.is_valid():
newstudent= form.save()
else:
form = NewStudentForm()
return render(request, 'forms/newstudentcheck_form.html', {'form': form})
Here is my test code to see if query is working correctly and i keep getting a error that the query set doesnt exists.
from .models import StudentCheck
from django.core.exceptions import ValidationError
from django.shortcuts import render
from django.http import HttpResponse, Http404, HttpResponseRedirect
from forms.forms import NewStudentForm
def NewStudentFormCheckList (request):
if request.method == 'POST':
form = NewStudentForm(request.POST)
lastname = StudentCheck.lastname
number_lastnames = StudentCheck.objects.get(lastname__exact=lastname)
if form.is_valid():
newstudent= form.save()
print (number_lastnames)
else:
form = NewStudentForm()
return render(request, 'forms/newstudentcheck_form.html', {'form': form})
You can get all the entries in the database which have a given value already set using the field lookup exact (see here for more informations).
In your case it'll be StudentCheck.objects.get(lastname__exact=yourvalue). This would give you a QuerySet, and if you want to know how many entries have the given last name, you have to use count() on this QuerySet to know how many entries it has.
You can use this solutions in two different places:
Directly in the view, when receiving the POST values.
In a custom validator, which would be used in the definition of the model (see here to know how to do)
I would recommend to use the second one, as it would be easier to provide custom information for the user on why it's data where not accepted.
Both of these methods requires the data to be passed to the server to be validated though. Otherwise you can define a view that would receive the lastname and return if it's present already in the database in some way (JSON for example), which would be called using Ajax when the user click on the submit button.
Edit:
As per request of OP, here's an example of the custom validator:
from django.core.exceptions import ValidationError
from .models import StudentCheck
def validate_lastname(value):
number_lastnames = StudentCheck.objects.get(lastname__exact=value)
if number_lastnames > 0:
raise ValidationError(
'%s already exists' % value,
)
Now you can use this custom validator with attribute validators, either in the definition of your model or inside the definition of your form like this: lastname = models.CharField(validators=[validate_lastname]).
Hope it helps!

Taking input in form and then comparing it with values stored in databse in django

I was working on a project where the user inputs the answer to the question and then the user input needs to be checked on clicking submit button. If input matches the answer stored in database in the admin portal then it should redirect it to a new page else it should give an error wrong answer.
What's happening is that for every user input i am redirected to the other page. But never shows Wrong Answer even if input other than that in database answer is entered. How do I tackle this?
forms.py
from django import forms
from .models import Answer
from django.core.exceptions import ObjectDoesNotExist
class CheckAnswer(forms.Form):
your_answer=forms.CharField(label='Answer')
def clean(self):
cleaned_data=super(CheckAnswer,self).clean()
response=cleaned_data.get("your_answer")
try:
p = Answer.objects.filter(answer__contains=response)
except Answer.DoesNotExist:
raise forms.ValidationError("Wrong Answer")
models.py
from django.db import models
from django.contrib.auth import get_user_model
User=get_user_model()
users=User.objects.all()
class Answer(models.Model):
name=models.CharField(max_length=10,unique=True)
answer=models.CharField(max_length=100)
def __str__(self):
return self.name
class Meta:
ordering= ["-name"]
views.py
from django.shortcuts import render,redirect
from django.views.generic import *
from . import models
from django import forms
from .forms import CheckAnswer
def Arena1(request):
if request.method=='POST':
form = CheckAnswer(request.POST)
if form.is_valid():
return redirect('thanks')
else:
form=CheckAnswer()
return render(request,'levels/arena1.html',{'form':form})
The Model Managers filter method does not raise DoesNotExist, you should use Answer.objects.get(answer__contains=response) to raise DoesNotExist, keep in mind that this can also return a MultipleObjectsReturned error if there is more than one answer matching your response, filter will just return an empty list.
The other option is to use Answer.objects.filter(answer__contains=response).exists() and check if it returns true or false.

Creating a sample application where Django Bulk Writes to Mongo Db after Sessions end

I want to be able to use Django Sessions and Mongo DB together to perform bulk writes to database after a Session. Later I want to be able to associate Users to Sessions and Events as well.
I have just started and I am new to Django . I am just running around tutorial after tutorial and so far I have just tried out some things and may have got a few things right I guess.
Any help with finding some right direction is appreciated.
Here is my views.py
# Create your views here.
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import render
from django.contrib.sessions.models import Session
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
import json
class Events(APIView):
def post(self,request,format=None):
try:
event_info = json.loads(request.body)
except ValueError:
return Response(status=status.HTTP_400_BAD_REQUEST)
if not request.session.session_key:
request.session.save()
sid = str(request.session.session_key)
settings.DB.events.insert(event_info, w=1)
return Response(sid,status=status.HTTP_200_OK)
events = Events.as_view()
models.py
from __future__ import unicode_literals
from django.db import models
from django.conf import settings
# Create your models here.
from django.contrib.sessions.models import Session
from django.contrib.auth.signals import user_logged_in
class EventsModel(object):
def __init__(self):
self.conn = pymongo.MongoClient()
self.db = conn.dev_db
def save(self, event_info):
"""
Save json object into mongodb Cluster
:param event_info:
:return:
"""
self.db.events.insert(event_info, w=1)

Categories