最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Access request session data of DetailView in CreateView in django - Stack Overflow

programmeradmin1浏览0评论

I am writing a library management system in Django. There are two views that I am having a bit of a struggle.

The BookDetailsView lists the details of a Book such as title, price, etc.

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)

In the BookBorrowView, I display a form where the reader can borrow a book. Two fields are preset (borrowers and book), and I don't want the user to be able to change them. At the moment, the user can select among many options.


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

The following is a screenshot of the form displayed by the BookBorrowView.

I have two questions:

  1. I am passing the primary key for the book through request.session so I can access it in the BookBorrowView to preset the book's title in the form. Is this a good approach?

  2. How can the two fields of the form be preset and unchanged by the user?

I am writing a library management system in Django. There are two views that I am having a bit of a struggle.

The BookDetailsView lists the details of a Book such as title, price, etc.

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)

In the BookBorrowView, I display a form where the reader can borrow a book. Two fields are preset (borrowers and book), and I don't want the user to be able to change them. At the moment, the user can select among many options.


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

The following is a screenshot of the form displayed by the BookBorrowView.

I have two questions:

  1. I am passing the primary key for the book through request.session so I can access it in the BookBorrowView to preset the book's title in the form. Is this a good approach?

  2. How can the two fields of the form be preset and unchanged by the user?

Share Improve this question asked Jan 22 at 16:40 holybullholybull 2,0362 gold badges18 silver badges18 bronze badges 1
  • Can you share the BookBorrowTransaction model? – willeM_ Van Onsem Commented Jan 22 at 17:16
Add a comment  | 

1 Answer 1

Reset to default 2

I am passing the primary key for the book through request.session so I can access it in the BookBorrowView to preset the book's title in the form. Is this a good approach?

I would say no. You usually pass it through a URL, this is more robust: it requires the variable to be set before you can trigger the view, since it is in the URL, and otherwise the path(…) [Django-doc] will not "fire". Furtermore session variables make the approach stateful. It means that if the session_id cookie expires a person will get a new session, and thus with new data. So while not very common, it is possible to first visit the book details, and when you want to borrow it, the session variable is expired.

so:

urlpatterns = [
    path('<int:pk>', BookDetailsView.as_view()),
    path('<int:book_id>/borrow', BookBorrowView.as_view()),
]

How can the two fields of the form be preset and unchanged by the user?

You can work with a custom field that thus disables the data, like:

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']

and plug it into the 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']),
        }

This will also prevent the form being tampered with: if you make a POST request with different values as form data, the form will take the initial ones.

发布评论

评论列表(0)

  1. 暂无评论