Django能在一个视图中处理多个ID吗?
为了在Django 4.2和Python中做一些练习,我正在创建一个项目,让用户可以查询和评价他们读过的书籍。现在,"library"应用中的"Book"表里已经有一些书籍了。我的目标是让用户可以把这些书籍添加到他们的个人区域,这些书籍会保存在"readers"应用的"UserBook"表中,以便他们可以后续添加笔记或分类。
为了实现这个功能,用户可以搜索一本书,如果这本书在"library"应用的"Book"数据库中存在,用户就可以进入书籍页面,点击“添加到我的书籍”按钮,这样书籍的信息就会自动复制到"readers"应用的"UserBook"表中,并在用户区域的书籍页面上显示出来。
这是"library"应用中的"Book"表:
class Book(Base):
class Meta:
verbose_name = 'Book'
verbose_name_plural = 'Books'
db_table = 'books'
cover = models.ImageField(upload_to='pictures/cover', blank=True, default='')
title = models.CharField('Title', max_length=100)
publisher = models.CharField('Publisher', max_length=100)
isbn = models.CharField('ISBN', unique=True, max_length=100)
nr_pages = models.IntegerField('Pages', null=True, blank=True)
synopsis = models.TextField('Synopsis', null=True, blank=True)
author = models.ManyToManyField(Author, verbose_name='Author(s)', related_name='book')
def __str__(self) -> str:
return self.title
这是url路径的代码,路径是'book/int:id/',对应的视图是views.single_book,按钮是“添加到我的书籍”:
<main class="main-content">
<div class="main-bg">
<section class="hero">
<img class="hero-content-img" src= {{ book.cover.url }} alt="Book cover of {{ book.title }}" >
<header class="hero-content">
<h2 class="hero-content-title">{{ book.title }}</h2>
<a class="hero-content-subtitle">
{% for author in book.author.all %}
{{ author.name }}{% if not forloop.last %}, {% endif %}
{% endfor %}
</a>
<div class="data-meta">
<span class="data-meta-text">ISBN: {{ book.isbn }}</span>
<span class="data-meta-text">Publisher: {{ book.publisher }}</span>
<span class="data-meta-text">Pages: {{ book.nr_pages }}</span>
</div>
<form action="{% url 'readers:book_review' book.id %}" method="post">
{% csrf_token %}
<button type="submit" class="start-reading-button">Add to My Books</button>
</form>
</header>
</section>
</div>
</main>
这是"readers"应用中的"UserBook"表:
class UserBook(Base):
class Meta:
verbose_name = 'My Book'
verbose_name_plural = 'My Books'
db_table = 'user_books'
cover = models.ImageField(upload_to='readers/cover', blank=True, default='')
title = models.CharField('Title', max_length=100)
publisher = models.CharField('Publisher', max_length=100)
isbn = models.CharField('ISBN', unique=True, max_length=100)
nr_pages = models.IntegerField('Pages', null=True, blank=True)
synopsis = models.TextField('Synopsis', null=True, blank=True)
author = models.CharField('Author(s)', max_length=255, null=True, blank=True)
owner = models.ForeignKey(User, related_name='books', on_delete=models.CASCADE,)
def __str__(self) -> str:
return self.title
这是展示书籍在用户区域的页面的视图,路径是'review/my_books/int:user_book_id/',对应的视图是views.book_review:
def book_review(request, user_book_id):
user_book = None # Inicialize user_book com None
if request.method == 'POST':
# Verifica se o livro existe
book = get_object_or_404(Book, pk=user_book_id)
# Verifica se o usuário já possui este livro
user_book_exists = UserBook.objects.filter(isbn=book.isbn, owner=request.user).exists()
if user_book_exists:
messages.error(request, "You already have this book in your collection.")
# Se o livro já existe, redirecione para a página de revisão do livro existente
user_book = UserBook.objects.get(isbn=book.isbn, owner=request.user)
return redirect('readers:book_review', user_book_id=user_book.id)
else:
# Cria um novo UserBook com os dados do livro
user_book = UserBook.objects.create(
cover=book.cover,
title=book.title,
publisher=book.publisher,
isbn=book.isbn,
nr_pages=book.nr_pages,
synopsis=book.synopsis,
author=", ".join([author.name for author in book.author.all()]),
owner=request.user
)
# Redireciona para a página de revisão do UserBook recém-criado
return redirect('readers:book_review', user_book_id=user_book.id)
print("User Book:", user_book)
# Redireciona para a página de revisão do UserBook correspondente (se existir)
if user_book is not None:
return redirect('readers:book_review', user_book_id=user_book.id)
else:
# Caso não haja user_book, renderize um template vazio ou redirecione para outra página
# Por exemplo, você pode retornar uma resposta HTTP com um status 404 (página não encontrada)
return HttpResponse("User Book not found", status=404)
我在这里遇到了困难,因为尽管在数据库的"UserBook"表中成功记录了数据,但在访问'review/my_books/int:user_book_id'时,显示的却是"Book"表中的id,而不是"UserBook"表中新生成的id,这样就导致了在展示正确的url时出现错误。请问有没有办法修改这个视图以保持这个逻辑,或者我该如何处理呢?
1 个回答
问题
我觉得问题出在第6行 book = get_object_or_404(Book, pk=user_book_id)
。你是在 Book
表里查找,但用的是来自 UserBook
表的主键来过滤。
解决方案
在HTML中,不要发送 user_book_id
,而是应该发送 book_id
。