Django Foreign Key Constraint failed after blank = True - python

I get an Integrity error, Foreign Key Constraint failed. I have the following function I am trying to run:
if request.method == "POST":
#Get token
access_token = AccessToken.objects.get(token = request.POST.get('access_token'),
expires__gt = timezone.now())
#Get profile
customer = access_token.user.customer
# Check if customer has a order that is not delivered
if Order.objects.filter(customer = customer).exclude(status = Order.DELIVERED):
return JsonResponse({"status": "fail", "error": "Your Last Order must be completed"})
# Check Address
if not request.POST["address"]:
return JsonResponse({"status": "failed", "error": "Address is required."})
# Ger Order Details
order_details = json.loads(request.POST["order_details"])
order_total = 0
for meal in order_details:
order_total += Meal.objects.get(id = meal["meal_id"]).price * meal["quantity"]
if len(order_details)>0:
# Step 1 - Create an Order
order = Order.objects.create(
customer = customer,
restaurant_id = request.POST["restaurant_id"],
total = order_total,
status = Order.PENDING,
address = request.POST["address"]
)
# Step 2 - Create Order details
for meal in order_details:
OrderDetails.objects.create(
order = order,
meal_id = meal["meal_id"],
quantity = meal["quantity"],
sub_total = Meal.objects.get(id = meal["meal_id"]).price * meal["quantity"]
)
return JsonResponse({"status": "success"})
Here is my order class:
Class Order(models.Model):
PENDING = 1
COOKING = 2
READY = 3
ONTHEWAY = 4
DELIVERED = 5
STATUS_CHOICES = (
(PENDING, "Pending"),
(COOKING, "Cooking"),
(READY, "Ready"),
(ONTHEWAY, "On The Way"),
(DELIVERED, "Delivered"),
)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
driver = models.ForeignKey(Driver, on_delete=models.CASCADE, blank = True, null = True)
address = models.CharField(max_length=500)
total = models.IntegerField()
status = models.IntegerField(choices = STATUS_CHOICES)
created_at = models.DateTimeField(default = timezone.now)
picked_at = models.DateTimeField(blank = True, null = True)
def __str__(self):
return str(self.id)
I previously got an error because Driver was not null so I added blank = True, null = True. Now it gives the Foreign Key Contraint Error.
I am testing the function is postman, and I do not define the driver anywhere, the driver is to be added later not while the function is called.
This is my views.py
def restaurant_add_meal(request):
form = MealForm()
if request.method == "POST":
form = MealForm(request.POST, request.FILES)
if form.is_valid():
meal = form.save(commit=False)
meal.restaurant = request.user.restaurant
meal.save()
return redirect(restaurant_meal)
return render(request, 'restaurant/add_meal.html', {
"form": form
})

I changed restaurant_id = request.POST["restaurant_id"] to
restaurant = Restaurant.objects.get(pk = request.POST["restaurant_id"])
and the error is fixed.

Related

'QuerySet' object has no attribute 'videos_set'

I am trying to get all the videos related to a curriculum, I've tried curriculum.videos.all but it return this error that says 'QuerySet' object has no attribute 'videos', i also tried using curriculum.videos_set.all then it shows the same error but this time with a 'QuerySet' object has no attribute 'videos_set'. what can be the issue with this problem?
models.py
class Course(models.Model):
course_title = models.CharField(max_length=100, null=True, blank=True)
slug = models.SlugField(unique=True)
course_thumbnail = models.ImageField(upload_to=user_directory_path, blank=True)
class Curriculum(models.Model):
course = models.ForeignKey(Course , null = False , on_delete=models.CASCADE, related_name="curriculum")
title = models.CharField(max_length = 100 , null = False)
slug = models.SlugField(unique=True)
def __str__(self):
return f'{self.course.course_title} - {self.title}'
class Video(models.Model):
title = models.CharField(max_length = 100 , null = False)
curriculum = models.ForeignKey(Curriculum , null = False , on_delete=models.CASCADE, related_name="videos")
serial_number = models.IntegerField(null=False)
video_id = models.CharField(max_length = 100 , null = False)
def __str__(self):
return self.title
Now this is the view that i have written for it
View.py
def course_details(request, course_slug):
if request.user.is_authenticated:
user = request.user
course = Course.objects.get(slug=course_slug)
course.views = course.views + 1
curriculum = Curriculum.objects.filter(course=course)
serial_number = request.GET.get('lecture')
# videos = curriculum.videos.all().order_by("serial_number")
# video_count = curriculum.videos.all().order_by("serial_number").count()
videos = Video.objects.filter(curriculum=curriculum).order_by("serial_number")
profile = Profile.objects.get(user=course.course_creator)
user_rating = CreatorRating.objects.filter(profile=profile).aggregate(Avg('rating'))['rating__avg']
profile = Profile.objects.get(user=user)
follow_status = Follow.objects.filter(following=course.course_creator, follower=request.user).exists()
followers_count = Follow.objects.filter(following=course.course_creator).count()
liked = CourseLikes.objects.filter(user=user, course=course).count()
post_tags_ids = course.tags.values_list('id', flat=True)
similar_posts = Course.objects.filter(tags__in=post_tags_ids).exclude(id=course.id)
similar_posts = similar_posts.annotate(same_tags=Count('tags')).order_by('-same_tags','-date_created')
rating_average = CourseRating.objects.filter(course=course).aggregate(Avg('rating'))['rating__avg']
reviews = CourseRating.objects.filter(active=True, course=course).order_by("-date")
reviews_count = CourseRating.objects.filter(active=True, course=course).count()
rating_count = CourseRating.objects.filter(course=course, rating__in=["3.0", "4.0", "5.0"]).count()
discussions = CourseDiscussion.objects.filter(active=True, course=course).order_by('-date')
enrolled_student_count = UserCourse.objects.filter(course=course).count()
user_courses = Course.objects.filter(course_creator=course.course_creator).count()
students_enrolled_for_a_creator = UserCourse.objects.filter(course__course_creator=course.course_creator).count()
all_star = CourseRating.objects.filter(course__course_creator=course.course_creator).count()
# lectures = Video.objects.filter(curriculum=curriculum).count()
recent_courses = Course.objects.filter(course_publish_status="published").order_by("?")[:3]
is_liked = False
if course.likes.filter(id=request.user.id).exists():
is_liked = True
is_saved = False
if profile.favourite_course.filter(slug=course_slug).exists():
is_saved = True
# Course Rating Feature
if request.method == "POST":
form = CourseRatingForm(request.POST)
if form.is_valid():
rating_form = form.save(commit=False)
rating_form.user = request.user
rating_form.course = course
rating_form.save()
messages.success(request, f'You review was sent successfully!')
return redirect("course:course-detail", course.slug)
else:
form = CourseRatingForm
# Course Discusion Feature
if request.method == "POST":
discform = CourseDiscussionForm(request.POST)
if discform.is_valid():
disc_form = discform.save(commit=False)
disc_form.user = request.user
disc_form.course = course
disc_form.save()
messages.success(request, f'Posted!')
return redirect("course:course-detail", course.slug)
else:
discform = CourseDiscussionForm
#For the color of the favorite button
if profile.favourite_course.filter(slug=course_slug).exists():
favorited = True
else:
favorited = False
if liked == True:
liked = True
else:
liked = False
if serial_number is None:
serial_number = 1
# if Video.objects.all().exists
# video, created = Video.objects.get_or_create(serial_number=serial_number, curriculum=curriculum)
video, created = Video.objects.get_or_create(serial_number=serial_number, curriculum=curriculum)
# video_count = Video.objects.get(serial_number=serial_number, course=course)
video.save()
if(video.is_preview is False):
if request.user.is_authenticated is False:
return redirect("course:sign-in")
else:
user = request.user
try:
user_course = UserCourse.objects.get(user=user, course=course)
except:
return redirect("course:check-out", slug=course.slug)
# if request.user.is_authenticated:
# student = request.user.student
# order, created = Order.objects.get_or_create(student=student, completed=False)
# items = order.orderitem_set.all()
# cartItems = order.get_cart_items
# else:
# items = []
course.save()
context = {
'enrolled_student_count':enrolled_student_count,
'user_courses':user_courses,
"reviews" : reviews,
# "lectures" : lectures,
"reviews_count" : reviews_count,
"rating_count" : rating_count,
"followers_count" : followers_count,
"follow_status" : follow_status,
"favorited" : favorited,
"all_star" : all_star,
"liked" : liked,
'recent_courses': recent_courses,
'is_liked': is_liked,
"video" : video,
"form" : form,
'discussions': discussions,
'discform': discform,
# "video_count" : video_count,
'videos':videos,
'course': course,
'students_enrolled_for_a_creator': students_enrolled_for_a_creator,
'is_saved':is_saved,
'rating_average':rating_average,
'user_rating':user_rating,
'similar_posts':similar_posts,
# 'cartItems': cartItems,
}
return render(request, 'course/course-detail.html', context)
else:
user = request.user
course = Course.objects.get(slug=course_slug)
course.views = course.views + 1
serial_number = request.GET.get('lecture')
videos = course.videos.all().order_by("serial_number")
video_count = course.videos.all().order_by("serial_number").count()
post_tags_ids = course.tags.values_list('id', flat=True)
similar_posts = Course.objects.filter(tags__in=post_tags_ids).exclude(id=course.id)
similar_posts = similar_posts.annotate(same_tags=Count('tags')).order_by('-same_tags','-date_created')
rating_average = CourseRating.objects.filter(course=course).aggregate(Avg('rating'))['rating__avg']
reviews = CourseRating.objects.filter(active=True, course=course).order_by("-date")
reviews_count = CourseRating.objects.filter(active=True, course=course).count()
rating_count = CourseRating.objects.filter(course=course, rating__in=["3.0", "4.0", "5.0"]).count()
discussions = CourseDiscussion.objects.filter(active=True, course=course).order_by('-date')
enrolled_student_count = UserCourse.objects.filter(course=course).count()
user_courses = Course.objects.filter(course_creator=course.course_creator).count()
students_enrolled_for_a_creator = UserCourse.objects.filter(course__course_creator=course.course_creator).count()
all_star = CourseRating.objects.filter(course__course_creator=course.course_creator).count()
lectures = Video.objects.filter(course=course).count()
recent_courses = Course.objects.filter(course_publish_status="published").order_by("?")[:3]
is_liked = False
if course.likes.filter(id=request.user.id).exists():
is_liked = True
is_saved = False
if serial_number is None:
serial_number = 1
# if Video.objects.all().exists
video, created = Video.objects.get_or_create(serial_number=serial_number, course=course)
video_count = Video.objects.get(serial_number=serial_number, course=course)
video.save()
if(video.is_preview is False):
if request.user.is_authenticated is False:
return redirect("course:sign-in")
else:
user = request.user
try:
user_course = UserCourse.objects.get(user=user, course=course)
except:
return redirect("course:check-out", slug=course.slug)
course.save()
context = {
'enrolled_student_count':enrolled_student_count,
'user_courses':user_courses,
"reviews" : reviews,
"lectures" : lectures,
"reviews_count" : reviews_count,
"rating_count" : rating_count,
'similar_posts':similar_posts,
"all_star" : all_star,
'recent_courses': recent_courses,
"video" : video,
'discussions': discussions,
"video_count" : video_count,
'videos':videos,
'course': course,
'students_enrolled_for_a_creator': students_enrolled_for_a_creator,
'is_saved':is_saved,
'rating_average':rating_average,
}
return render(request, 'course/course-detail.html', context)
You should query like this using filter() if you want to get all videos related to curriculum:
# #login_required
def course_details(request, course_slug):
if request.user.is_authenticated:
user = request.user
course = Course.objects.get(slug=course_slug)
curriculum = Curriculum.objects.filter(course=course)
serial_number = request.GET.get('lecture')
videos = Video.objects.filter(curriculum=curriculum).order_by('serial_number')
...
Note: It is generally better to use get_object_or_404 instead of get(), it automatically handles http 404 error.
Use as:
course = get_object_or_404(Course,slug=course_slug)
You have to use the Video manager and filter by the curriculum instance.
Try it like this:
# #login_required
def course_details(request, course_slug):
if request.user.is_authenticated:
user = request.user
course = Course.objects.get(slug=course_slug)
curriculum = Curriculum.objects.filter(course=course)
serial_number = request.GET.get('lecture')
videos = Video.objects.filter(curriculum=curriculum).order_by('serial_number')
...
More info in the official docu

Django: how to save data to database in django when a condition is met?

i am writing a logic to allow user pay for items using thier debit card, the logic is working fine. Now i want to save some data to the database when the status=successful.
When a user purchase a course i want to add the course and the user who purchased the course to a model that i have created called UserCourse.
I have tried adding slug to the process_payment view that i created but it seems not to be working. I also have another view called payment_response that checks if a payment was success or not.
How do i add the purchased course and the user that purchase the course in the db?
views.py
# The course detail view
def course_details(request, course_slug):
if request.user.is_authenticated:
user = request.user
course = Course.objects.get(slug=course_slug)
#login_required
def course_checkout(request, slug):
course = Course.objects.get(slug=slug)
user = request.user
# form to get the student's name, email, amount of course
if request.method == "POST":
course = Course.objects.get(slug=slug)
name = request.POST.get("name")
email = request.POST.get("email")
amount = request.POST.get("amount")
return redirect(str(process_payment(name,email,amount, course)))
else:
pass
# how to handle courses that are free
if amount == 0:
course = Course.objects.get(slug=slug)
userCourse = UserCourse(user=user, course=course)
userCourse.save()
return redirect('course:course-content', course.slug)
# View that processes the payment
def process_payment(name,email,amount):
auth_token= settings.FLUTTER_SECRET_KEY
hed = {'Authorization': 'Bearer ' + auth_token}
data = {
"tx_ref":''+str(math.floor(1000000 + random.random()*9000000)),
"amount":amount,
"currency":"USD",
"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":"DexxaEd",
"description":" Limitless Learning For Everyone",
"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
# view that check for payment status
#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)
if status == "successful":
# return HttpResponse('Payment Successful')
return render(request, "payment/payment-success.html")
if status == "cancelled":
return render(request, "payment/payment-failed.html")
# return HttpResponse('Payment Cancelled')
models.py
class Course(models.Model):
course_title = models.CharField(max_length=100, null=True, blank=True)
slug = models.SlugField(unique=True)
price = models.IntegerField(default=0, null=True, blank=True)
course_creator = models.ForeignKey(User, on_delete=models.CASCADE)
# Model that store the purchased courses
class UserCourse(models.Model):
user = models.ForeignKey(User , null = False , on_delete=models.CASCADE)
course = models.ForeignKey(Course , null = False , on_delete=models.CASCADE, related_name="usercourse")
date = models.DateTimeField(auto_now_add=True)
urls.py
path('callback', payment_response, name='payment_response')
First update your UserCourse to include paid field as
class UserCourse(models.Model):
# your previous fields
paid = models.BooleanField(default=False)
In the course checkout function create usercourse object if it is a free couse paid is set True else False
def course_checkout(request, slug):
# previous code
if request.method == "POST":
# your existing code
user_course = UserCourse.objects.create(user=user, course=course)
user_course_id = user_course.id
# your existing code
return redirect(str(process_payment(name, email, amount, course, user_course_id)))
# your other code logic
if amount == 0:
user_course = UserCourse.objects.create(user=user, course=course, paid=True)
# your other code logic
In the payment_response function provide user_course_id url arguments as
def payment_response(request, user_course_id=None):
status=request.GET.get('status', None)
tx_ref=request.GET.get('tx_ref', None)
if status == "successful":
if user_course_id:
UserCourse.objects.filter(id=user_course_id).update(paid=True)
return render(request, "payment/payment-success.html")
else:
return render(request, "payment/payment-failed.html")
if status == "cancelled":
return render(request, "payment/payment-failed.html")
In the process payment view;
def process_payment(name, email, amount, course, user_course_id):
# your existing code only change redirection url in data as
{
"redirect_url":f"http://localhost:8000/callback/{user_course_id}/",
}
In urls.py
path('callback/<int:user_course_id>/', payment_response, name='payment_response')

Cannot assign "(<Qualification: Qualification object (1)>,)": "QualificationApproval.qtitle" must be a "Qualification" instance

this is my model of Qualification Approval
class QualificationApproval(models.Model):
"""Model definition for QualificationApproval."""
# TODO: Define fields here
qtitle = models.ForeignKey(Qualification, on_delete=models.CASCADE)
ofEqualCode = models.CharField(max_length=100)
porposDate = models.DateField()
anNo = models.IntegerField()
status = models.CharField(max_length= 50, default="pending")
sec9 = models.ForeignKey(Sec9, on_delete=models.CASCADE)
class Meta:
"""Meta definition for QualificationApproval."""
verbose_name = 'QualificationApproval'
verbose_name_plural = 'QualificationApprovals'
so here is qtitle is foreign key of qualification
the problem is that when I assign the qualification in QualifcationApproval so its give me and error
def sec9edit(request, secId):
if 'userId' not in request.session:
return render(request, "front/login.html", {
"message": "Login Required First"
})
user = User.objects.get(pk = request.session['userId'])
sec1 = Sec1.objects.get(user = user )
qualification = Qualification.objects.all()
if request.method == "POST" and secId:
sec9 = Sec9.objects.get(pk = secId)
sec9.curriculum = request.POST['curriculum']
sec9.save()
qlrn = request.POST.getlist('qualification')
code = request.POST.getlist('code')
pdate = request.POST.getlist('pdate')
anticipated = request.POST.getlist('anticipated')
j = 0
qa = QualificationApproval.objects.filter(sec9 = sec9)
for q in qlrn:
if q:
qua = Qualification.objects.get(pk = q.split(',')[0])
print(type(qa[j].qtitle))
qa[j].qtitle = qua,
qa[j].ofEqualCode = code[j],
qa[j].porposDate = pdate[j],
qa[j].anNo = anticipated[j],
qa[j].sec9 = sec9
qa[j].save()
messages.success(request, 'Section 9 udpated successfully')
return HttpResponseRedirect(reverse('addCentre/sec10'))
else:
try:
sec9 = Sec9.objects.get(sec1= sec1)
qa = QualificationApproval.objects.filter(sec9 = sec9)
except:
return render(request, "front/sec9.html", {
"qualification": qualification
})
return render(request, "front/sec9.html", {
"qualification": qualification,
"sec9": sec9,
"qa": qa
})
I print the qa.qtitle it give me the result
<class 'lrnadmin.models.Qualification'>
but when I assign
it shows this error
ValueError: Cannot assign "(<Qualification: Qualification object (1)>,)": "QualificationApproval.qtitle" must be a "Qualification" instance.
you have additional , at the end
# ↓ delete this commas
qa[j].qtitle = qua, ↓
qa[j].ofEqualCode = code[j],
qa[j].porposDate = pdate[j],
qa[j].anNo = anticipated[j],
should be like this:
qa[j].qtitle = qua
qa[j].ofEqualCode = code[j]
qa[j].porposDate = pdate[j]
qa[j].anNo = anticipated[j]

unable to show success page after completion of payment

i am using razorpay payment gateway web integration for my learning eccomerce project everyhing work fine payment can be done all i want is to store some information after payment done in my order model using test mode
my views.py for checkout
class Checkout_Pre(View):
def post (self, request,):
user = request.user
address = Address.objects.filter(default=True, user=request.user)
cart = request.session.get('cart')
items = Item.get_items_by_id(list(cart.keys()))
prefer = request.POST.get('payment')
total_price = request.POST.get('paying_price')
total_item_price = json.loads(total_price)
with transaction.atomic():
order = Order.objects.create(
user=user,
total_price=total_item_price,
address=address.first(),
method = prefer,
)
for item in items:
item_order = OrderItem.objects.create(
order=order,
item=item,
size=cart.get(str(item.id)),
price=item.price,
)
request.session['cart'] = {}
order_currency = 'INR'
callback_url = 'http://'+ str(get_current_site(request))+"/handlerequest/"
print(callback_url)
notes = {'order-type': "Basic order from the coolbuy website", 'key':'value'}
razorpay_order = razorpay_client.order.create(dict(amount=total_item_price*100, currency=order_currency, notes = notes, receipt=order.order_id, payment_capture='0'))
print(razorpay_order['id'])
order.razorpay_order_id = razorpay_order['id']
order.save()
return render(request, 'payment/razorpaypaymentsummary.html', {'order':order, 'order_id': razorpay_order['id'], 'orderId':order.order_id, 'final_price':total_item_price, 'razorpay_merchant_id':settings.razorpay_id, 'callback_url':callback_url,})
so what the error is after payment completion i want to show html page and change sttus in db but after payment completion the handlerequest throwinh me http 505 error
#csrf_exempt
def handlerequest(request):
if request.method == "POST":
try:
payment_id = request.POST.get('razorpay_payment_id', '')
order_id = request.POST.get('razorpay_order_id','')
signature = request.POST.get('razorpay_signature','')
params_dict = {
'razorpay_order_id': order_id,
'razorpay_payment_id': payment_id,
'razorpay_signature': signature
}
try:
order_db = Order.objects.get(razorpay_order_id=order_id)
except:
return HttpResponse("505 Not Found")
order_db.razorpay_payment_id = payment_id
order_db.razorpay_signature = signature
order_db.save()
result = razorpay_client.utility.verify_payment_signature(params_dict)
if result==None:
amount = order_db.total_amount * 100 #we have to pass in paisa
try:
razorpay_client.payment.capture(payment_id, amount)
order_db.payment_status = 1
order_db.save()
return render(request, 'firstapp/payment/paymentsuccess.html',{'id':order_db.id})
except:
order_db.payment_status = 2
order_db.save()
return render(request, 'firstapp/payment/paymentfailed.html')
else:
order_db.payment_status = 2
order_db.save()
return render(request, 'firstapp/payment/paymentfailed.html')
except:
return HttpResponse("505 not found")
any idea what i am doing wrong here in my handlre request view
order model
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE,)
address = models.ForeignKey(Address, default= True, on_delete=models.CASCADE)
status = models.IntegerField(choices = status_choices, default=1)
method = models.CharField(max_length=50, blank=False,)
total_price = models.FloatField(blank=False, default=0)
payment_status = models.IntegerField(choices = payment_status_choices, default=3)
order_id = models.CharField(unique=True, max_length=200, null=True, default=None)
datetime_of_payment = models.DateTimeField(default=timezone.now)
created_at = models.TimeField(auto_now=True, editable=False)
razorpay_order_id = models.CharField(max_length=1000, null=True, blank=True)
razorpay_payment_id = models.CharField(max_length=1000, null=True, blank=True)
razorpay_signature = models.CharField(max_length=1000, null=True, blank=True)
def __str__(self):
return self.user.username + " " + str(self.order_id)
def save(self, *args, **kwargs):
if self.order_id is None and self.datetime_of_payment:
self.order_id = self.datetime_of_payment.strftime('ORDER%Y%m%dODR')
return super(Order,self).save(*args, **kwargs)
The problem is not with your view but with the save method of your model.
in the else part you are doing nothing. You should call the super generally.
Please modify the save function as below and then try :
def save(self, *args, **kwargs):
if self.order_id is None and self.datetime_of_payment:
self.order_id = self.datetime_of_payment.strftime('ORDER%Y%m%dODR')
return super(Order,self).save(*args, **kwargs)
In your post method, after you assign
order.razorpay_order_id = razorpay_order['id']
you need to save it. Looks like that's missing.
In your checkout view
def get(self, request, *args, **kwargs):
order = Order.objects.get(pk = self.kwargs['order'])
settings = SiteSettings.objects.all().first()
# Razorpay client auth
client = razorpay.Client(auth = (settings.razorpay_client_id, settings.razorpay_secret))
if order.razorpay_order_id is None:
order_amount = order.total*100
order_currency = settings.currency
order_receipt = 'Reciept'
notes = {'id': order.id, 'email': order.email_id, 'date':str(datetime.now()), 'amount': order.total, 'is_ios': order.is_ios, 'is_android': order.is_android} # OPTIONAL
data = {"amount":order_amount, "currency":order_currency, "receipt":order_receipt, "notes":notes, "payment_capture":'0'}
razorpay_order = client.order.create(data = data)
# Razorpay order inserted into database order
order.razorpay_order_id = razorpay_order["id"]
order.save()
else:
razorpay_order = client.order.fetch(order.razorpay_order_id)
return render(request, self.template_name, {'settings':settings, 'order':order, 'razorpay_order': razorpay_order})
def post(self, request, *args, **kwargs):
o = self.kwargs['order']+ ' POST'
settings = SiteSettings.objects.all().first()
return render(request, self.template_name, {'settings':settings, 'order':o})
In your handler
settings = SiteSettings.objects.all().first()
order = Order.objects.get(id=request.POST.get('order_id'))
#Razorpay authentication
client = razorpay.Client(auth = (settings.razorpay_client_id, settings.razorpay_secret))
#Razorpay transaction details
razorpay_transaction_details = {
'razorpay_order_id': request.POST.get('razorpay_order_id'),
'razorpay_payment_id': request.POST.get('razorpay_payment_id'),
'razorpay_signature': request.POST.get('razorpay_signature')
}
#Razorpay payment verification
client.utility.verify_payment_signature(razorpay_transaction_details)
#Razorpay capture payment Make sure you change this accordingly.
payment_transaction_details = client.payment.capture(razorpay_transaction_details['razorpay_payment_id'], order.total*100, {"currency":"payment_currency"})
order.order_description = payment_transaction_details
order.status = 'paid'
order.save()
context = {'request': request.POST, 'order': order, 'settings':settings, 'UserData':UserData, 'Password': Password}
return render(request, 'web/rpay-success.html', context)
You can wrap a try except block in it to render failure.

Update db on successful payment django

I have a model named 'Exhibition', where i enable users to create a new exhibition/event after filling out a form they are asked to pay some amount and are redirected to a payment gateway (paypal as per django-paypal), after successful payment i want to update my 'Exhibition' table only for those who have paid, users are requested to login before creating an event and i am also saving the user with the form in my db.
This is my view for saving the form:
def new_event(request):
form = NewEventForm(request.POST or None)
if form.is_valid():
save_it = form.save(commit=False)
save_it.user = request.user
save_it.save()
return render_to_response('new_event.html',locals(), context_instance=RequestContext(request))
and my model:
class Exhibition(models.Model):
user = models.ForeignKey(User, blank=True, null = True)
Type = models.ForeignKey('home.Type')
Category = models.ForeignKey('home.Category')
Country = models.ForeignKey('home.Country')
City = models.ForeignKey('home.City')
Event_name = models.CharField(max_length = 250)
Video_url = models.URLField(blank = True)
Event_start_date = models.DateField(blank = False)
Event_end_date = models.DateField(blank = False)
Discription = RichTextField(blank = False)
Contact_person = models.CharField(max_length=50,blank = True )
Company = models.CharField(max_length = 100,blank = True)
Company_website = models.URLField(blank = True)
Email = models.EmailField(blank = True)
Event_website = models.URLField(blank = True)
Event_email = models.EmailField(blank = True)
Venue = models.CharField(max_length = 250, blank = False)
Address = models.CharField(max_length = 250, blank = False)
Paid = models.IntegerField(max_length=2, default='0')
def __unicode__(self):
return '%s' % self.Event_name
#permalink
def get_absolute_url(self):
return ('view_category', None, { 'slug': self.Event_name })
If i use django-paypal view, i would be able to process payment but i don't know how to get the correct 'Exhibition - id' to update the db, shall i store it in cookies and how to do it?
I would try adding a post_save signal handler to django-paypal's model PayPalStandardBase and then use the transaction record's fields to identify your exhibition record. You could use the primary key field of your model and tell paypal that it is your item number for the transaction, or just add any other unique field you want to use as common identifier.
Check out the model here:
https://github.com/spookylukey/django-paypal/blob/master/paypal/standard/models.py
The signal handler would look like:
#receiver(post_save, sender=PayPalStandardBase)
def mark_as_paid(sender, instance=None, created=False, **kwargs):
if created:
e = Exhibition.objects.get(pk=instance.item_number)
e.Paid = ...
e.save()
You can add it to a models.py of yours or a signals.py which you then import elsewhere.
I would suggest adding a custom field containing the user id , and recover it when paypal notify you back.
See custom below :
https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNandPDTVariables/

Categories

Resources