Django redirect to DetailView From FormView

Viewed 78

What I'm trying to do is to have a form with a single field that gets a primary key and redirects to DetailView of that primary key. While I can achieve this by having a ListView and then go to the DetailView from ListView that's an extra step I don't need as I already have a primary key. Any help would be appreciated.

models.py

class Book(models.model):
    book_id = models.TextField(primary_key=True)
    # some other fields
    def get_absolute_url(self):
        return reverse('book-detail', kwargs={'pk':self.pk})

forms.py

class BookSearchForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['book_id']

views.py

class BookDetailView(DetailView):
    model = Book
    template_name = 'book-detail.html'

with a ListView I can do it like below:

class BookListView(ListView):
    template_name = 'book-list.html'
    form_class = BookSearchForm

    def get_queryset(self, *args, **kwargs):
        qs = super().get_queryset(*args, **kwargs)
        book_id = self.request.Get.get('book_id', None)
        if book_id:
            qs=qs.filter(book_id=book_id).first()
        if not book_id:
            qs=qs.none()
        return qs

How can I do it without a ListView??

class BookSearchView(FormView):
    template_name = 'book-search.html'
    form_class = BookSearchForm
    # what should I do here, form_valid, get?

urls.py

urlpatterns = [
    path('book/search/',BookSearchView.as_view(),name='book-search'),
    path('book/<str:pk>/',BookDetailView.as_view(),name='book-detail')
]

book-search.html

<form action="." method="GET">
    {{form}}
</form>
1 Answers

Well to redirect to the DetailView you can specify a success url in your FormView like so:

class BookSearchView(FormView):
    template_name = 'book-search.html'
    form_class = BookSearchForm
    success_url = '' # The url that you want to direct after form is validated 
    
     def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # It should return an HttpResponse.
        
        return super().form_valid(form)
Related