I got this problem where Django return “No Books matches the given query”, even though the object exist in database.
For context, I want to create an update page without relying the use of URL. First, here is my model :
User = get_user_model()
class Books(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
title = models.CharField(max_length=50)
author = models.CharField(
max_length=40,
)
author_nationality = models.CharField(max_length=20, default='Japanese')
author_medsos = models.CharField(max_length=30, default='None')
book_type = models.CharField(
max_length=10,
null=True,
choices=BOOKS_TYPES
)
tl_type = models.CharField(
max_length=20,
null=True,
choices=TRANSLATION_BY
)
series_status = models.CharField(
max_length=20,
choices=SERIES_STATUS,
default=ONG
)
source = models.CharField(max_length=100) # source can refer to downloage page, example = https://www.justlightnovels.com/2023/03/hollow-regalia/
reading_status = models.CharField(
max_length=20,
choices=READING_STATUS,
default=TOR
)
current_progress = models.CharField( # For tracking how many chapter have been read
max_length=30,
null=True
)
cover = models.FileField(upload_to='cover/', default='cover/default.png')
genre = models.CharField(max_length=40, null=True)
class Review(models.Model):
books = models.ForeignKey('Books', on_delete=models.CASCADE, null=True)
volume = models.IntegerField()
review = models.TextField()
Before the user get to the update page, they first have to visit /library
page :
{% for book in user_books %}
<div class='lib-item'>
<form method='POST' action="{% url 'core:update_library' %}">
{% csrf_token %}
<input type='hidden' name='book_id' value='{{ book.id }}'>
<button type='submit'>
<img src={{ book.cover.url }} width='185'>
<span>
{{ book.title }}
</span>
</button>
</form>
</div>
{% endfor %}
Notice the hidden input? The idea is to pass the book.id to the next page, which is /library/update
. Here is the page for /library/update
:
{% block content %}
<div class='content'>
<h3>{{ book.title }} by {{ book.author }}</h3>
<small> _id : {{ book_id }} </small>
<small> id : {{ book }} </small>
<form method='POST'>
{% csrf_token %}
{{ form.as_p }}
<button type='submit'>submit</button>
</form>
{% endblock %}
And here is the views.py for both page
@login_required
def library(request):
user = request.user
user_books = user.books_set.all()
context = {
'user' : user,
'user_books' : user_books
}
return render(request, 'user_library.html', context)
@login_required
def update_library(request):
user = request.user
book_id = request.POST.get('book_id')
# book = user.books_set.get(pk=book_id)
book = get_object_or_404(user.books_set, pk=book_id)
if request.method == 'POST':
form = UpdateBooks(request.POST, instance=book)
if form.is_valid():
form.save()
context = {
'book_id' : book_id,
'book' : book,
'form' : form
}
# messages.success(request, 'Library have been updated')
# return HttpResponseRedirect('/library/update/')
return render(request, 'user_update.html', context)
else :
context = {
'book_id' : book_id,
'book' : book
}
return render(request, 'user_update.html', context)
And the form using ModelForm :
class AddBooks(forms.ModelForm):
class Meta:
model = Books
exclude = ["owner"]
class UpdateBooks(forms.ModelForm):
class Meta:
model = Review
exclude = ["books"]
Now, when the user load the /library
page, the page works fine. When user choose a book, they are redirected to /library/update
with the book’s id being passed with the use of hidden input
. And the /library/update
able to display the information about the chosen book correctly, including the id, object, title, and author. So the book’s id should be present right?
But when the user submit the form, the page return an error : “Page not found (404) No Books matches the given query”.
I am confused as to why the error says there is “No Books matches the given query”. I have check Django admin page and the object exist. Even the /library/update
is correctly displaying the information about the books, so the book object should exist. But when submitting the form, the books does not exist.
Does anyone have any ideas about this error happens?
Thank you