在django中的CreateView中访问DetailView的请求会话数据

问题描述 投票:0回答:1

我正在用 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显示的表单的屏幕截图。

enter image description here

我有两个问题:

  1. 我通过 request.session 传递书籍的主键,以便我可以在 BookBorrowView 中访问它,以在表单中预设书籍的标题。这是一个好方法吗?

  2. 表单的两个字段如何能够被用户预设且不改变?

django
1个回答
0
投票

我通过 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
的值。

	

© www.soinside.com 2019 - 2024. All rights reserved.