我正在用 Django 编写一个图书馆管理系统。有两种观点认为我有点挣扎。
BookDetailsView 列出书籍的详细信息,例如标题、价格等。
class BookDetailsView(LoginRequiredMixin, DetailView):
model = Book
template_name = 'book_detail.html'
def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs)
request.session['book_pk'] = kwargs['pk']
return response
# used to mark book as read or unread
def post(self, request, *args, **kwargs):
if 'is_read' in request.POST:
book = Book.objects.get(pk=kwargs['pk'])
book.is_read = True
book.save()
return HttpResponseRedirect(self.request.path_info)
在 BookBorrowView 中,我显示了一个读者可以借书的表单。预设了两个字段(借款人和书籍),我不希望用户能够更改它们。目前,用户可以在许多选项中进行选择。
class BookBorrowView(LoginRequiredMixin, CreateView):
model = BookBorrowTransaction
template_name = 'book_borrow.html'
fields = ['book', 'borrowers', 'date_borrowed', 'to_return', ]
success_url = reverse_lazy('home')
def get_initial(self):
initial = super(BookBorrowView, self).get_initial()
initial['borrowers'] = get_object_or_404(CustomUser, email=self.request.user.email)
initial['book'] = get_object_or_404(Book, title=Book.objects.get(pk=self.request.session['book_pk']).title) # need the book id here
print(self.request.GET)
print(self.request.POST)
print(self.request.session['book_pk'])
return initial
以下是BookBorrowView显示的表单的屏幕截图。
我有两个问题:
我通过 request.session 传递书籍的主键,以便我可以在 BookBorrowView 中访问它,以在表单中预设书籍的标题。这是一个好方法吗?
表单的两个字段如何能够被用户预设且不改变?
我通过 request.session 传递书籍的主键,以便我可以在 BookBorrowView 中访问它,以在表单中预设书籍的标题。这是一个好方法吗?
我会说不。您通常通过 URL 传递它,这更稳健:它要求在触发视图之前设置变量,因为它位于 URL 中,否则
path(…)
[Django-doc] 不会“着火”。此外,会话变量使该方法具有“有状态”。这意味着如果 session_id
cookie 过期,用户将获得新的会话,从而获得新的数据。因此,虽然不太常见,但可以先访问图书详细信息,当您想借书时,会话变量已过期。
所以:
urlpatterns = [
path('<int:pk>', BookDetailsView.as_view()),
path('<int:book_id>/borrow', BookBorrowView.as_view()),
]
表单的两个字段如何能够被用户预设且不改变?
您可以使用自定义字段来禁用数据,例如:
class BookBorrowTransaction(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['book'].disabled = True
self.fields['borrowers'].disabled = True
class Meta:
model = BookBorrowTransaction
fields = ['book', 'borrowers', 'date_borrowed', 'to_return']
并将其插入
BookBorrowView
:
class BookBorrowView(LoginRequiredMixin, CreateView):
model = BookBorrowTransaction
template_name = 'book_borrow.html'
form_class = BookBorrowTransaction
success_url = reverse_lazy('home')
def get_initial(self):
return {
**super().get_initial()
'borrowers': self.request.user,
'book': get_object_or_404(Book, pk=self.kwargs['book_id'])
}
这也将防止表单被篡改:如果您使用不同的值作为表单数据发出 POST 请求,表单将采用 initial
的值。