Reputation: 27
I am building a website where users can buy courses and the courses will display on their users library, a site similar to gumroad, but i am getting this error when i clicked on the payment option on my code.
Here is the error messages i am getting MultipleObjectsReturned at /course/eyime/user_library/
get() returned more than one UserLibrary -- it returned 2!
here is the Views.py codes
@login_required
def user_library(request, username):
user = get_object_or_404(User, username=username)
my_library = UserLibrary.objects.filter(user=user)
if request.method == 'POST':
course_id = request.POST['course_id']
course_price = request.POST['course_price']
course = UserLibrary.objects.get(courses__id=course_id)
"""for c in course.courses.all():
print(c.name)"""
context = {
'course': course,
'course_price': course_price,
'email': request.user.email,
'phone': request.user.phone_number,
}
return render(request, 'courses/content/pay_for_courses.html', context)
return render(request, 'courses/content/user_library.html', {'my_library': my_library})
here is the html codes for payment of the courses
{% extends "jtalks/base.html" %}
{% load static %}
{% block title %}Payment With Paystack{% endblock %}
{% block content %}
<div class='container' onload="payWithPaystack()">
<div class='row justify-content-md-center'>
<div class='col-md-auto'>
<div id="output">
</div>
<div id="success">
</div>
<div id="display_info" style="display: none">
<p>Click <a href="{% url 'courses:print_course_pdf' course.id %}" target="_blank">Here</a> to print receipt of your purchase</p>
<p id="home">Go Back Home <a href="{% url 'jtalks:jtalks-home' %}">Homepage</a></p>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block js %}
<script src="https://js.paystack.co/v1/inline.js"></script>
<script>
window.onload=function(){
payWithPaystack();
};
function payWithPaystack(){
var price = '{{ course_price }}';
var handler = PaystackPop.setup({
key: 'pk_test_ce8979497f703eb955ab5ceb19fc54cdcb615e0d',
email:'{{email}}',
amount: parseInt(price) * 100,
currency: "NGN",
metadata: {
custom_fields: [
{
display_name: "Mobile Number",
variable_name: "mobile_number",
value: "{{phone}}",
course_id: "{{ course.id }}"
}
]
},
callback: function(response){
var ref = response.reference;
var course_random_id = '{{ course.order_id }}'
var course_id = '{{ course.id }}'
//console.log(order_id)
// $('div#home').show();
$.ajax({
method: "GET",
url: "/course/pay_for_courses/",
data: {
'id': course_id,
'reference': ref,
},
dataType: "json",
success: function (data) {
if (data.message == "Your Payment was successfully received") {
$('#output').html(data.message)
$('#success').html(`<p>Transaction reference is : <h2>${ref}</h2> and your order id is <h2>${course_random_id}</h2></p>`);
$("#display_info").show();
} else if (data.message == "Your Payment Failed!!!") {
$('#output').html(data.message)
$("#success").html(`<a href="{% url 'courses:user_library' %}" class="button">Back To Your Library</a>`)
}
},
});
},
onClose: function(){
alert('window closed');
}
});
handler.openIframe();
}
</script>
{% endblock js %}
and here is the html codes for users library
{% extends 'jtalks/base.html' %}
{%load static%}
{% block content %}
<div>
<center>Welcome to your library, {{ request.user.username }}</center>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-6">
<h1>Wish List</h1>
<h3>Courses you are yet to pay for will show up here</h3>
<div class="user_library" style="display: flex; flex-direction: row; flex-wrap: wrap;">
{% for library in my_library %}
{% if not library.paid %}
{% for course in library.courses.all %}
<div class="card" style="width: 18rem;">
<img src="{{ course.content_file.url }}" class="card-img-top" alt="{{ course.name }}">
<div class="card-body">
<h5 class="card-title">{{ course.name }}</h5>
<p class="card-text">{{ course.overview|slice:":50" }}...</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
</ul>
<div class="card-body">
<a href="{% url 'courses:course_detail' course.id course.slug %}" class="btn btn-primary">Course Details</a>
<form method="post">
{% csrf_token %}
<input type="hidden" name="course_id" value="{{ course.id }}">
<input type="hidden" name="course_price" value="{{ course.price }}">
<input type="submit" class="btn btn-primary" value="Pay ₦{{ course.price}}">
</form>
</div>
</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
<div class="col-6">
<h1>Paid Courses</h1>
<h3>All courses you have successfully paid for will show here</h3>
<div class="user_library" style="display: flex; flex-direction: row; flex-wrap: wrap;">
{% for library in my_library %}
{% if library.paid %}
{% for course in library.courses.all %}
<div class="card" style="width: 18rem;">
<img src="{{ course.content_file.url }}" class="card-img-top" alt="{{ course.name }}">
<div class="card-body">
<h5 class="card-title">{{ course.name }}</h5>
<p class="card-text">{{ course.overview|slice:":50" }}...</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
</ul>
<div class="card-body">
<a href="{% url 'courses:course_detail' course.id course.slug %}" class="btn btn-primary">Course Details</a>
<a id="download_pdf" href="/media/pdf_courses/{{ course.slug }}.pdf" class="btn btn-primary" download>Download PDF</a>
</div>
<div>
<video width="300" height="240" controls controlsList="nodownload">
<source src="{{ MEDIA_URL}}{{ course.course_video }}" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
</div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'jtalks/home.js' %}"></script>
{% endblock js %}
Upvotes: 0
Views: 116
Reputation: 306
It seems that this line is returning 2 records instead of one:
course = UserLibrary.objects.get(courses__id=course_id)
Use filter
instead of get
and iterate through the course
variable in a template tag such as:
{% for c in course %}
and access c's fields instead.
Upvotes: 1