Sam B.
Sam B.

Reputation: 3043

Django Class Based View return view or redirect to another page

I'm rewriting my function to class based views, this is the function I currently have.

@login_required
def invoice(request, invoice_no, template_name="invoice.html"):
    context = {}
    invoice_exists = Invoice.objects.filter(invoice_no=invoice_no)
    if invoice_exists:
        context['invoice'] = invoice_exists.first()
    else:
        return HttpResponseRedirect(reverse('invoices'))

    return render(request, template_name, context)

you have to be logged in, it filters using a filter named invoice_no

path('invoice/<int:invoice_no>', views.InvoiceView.as_view(), name="invoice"),

and if a match is found returns it, if not redirects you back to the invoices page.

this is what I have as a class

class InvoiceView(DetailView):
    queryset = Invoice.objects.all()
    context_object_name = 'invoice'
    pk_url_kwarg = 'invoice_no'
    template_name = "invoice.html"

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super().dispatch(*args, **kwargs)

    def get_object(self):
        obj = super().get_object()
        return obj

also the get object or 404 will do also since all it needs is a 404 page and it'll work.

Upvotes: 0

Views: 45

Answers (2)

Fomalhaut
Fomalhaut

Reputation: 9825

Try this:

class ArticleDetailView(LoginRequiredMixin, DetailView):
    template_name = "invoice.html"
    context_object_name = 'invoice'
    model = Invoice

    def dispatch(self, request, *args, **kwargs):
        try:
            return super().dispatch(request, *args, **kwargs)
        except Invoice.DoesNotExist:
            return HttpResponseRedirect(reverse('invoices'))

    def get_object(self):
        return Invoice.objects.get(invoice_no=self.kwargs['invoice_no'])

Upvotes: 1

Steven
Steven

Reputation: 538

Adjust according to your code.

from django.contrib.auth.mixins import LoginRequiredMixin

class InvoiceView(LoginRequiredMixin, DetailView):
    template_name = "invoice.html"
    context_object_name = 'invoice'

    def get_queryset(self, *args, **kwargs):
        invoice = get_object_or_404(Invoice, invoice_no=kwargs['invoice_no'])
        return invoice

This will however return a 404 page if no data is found, if you like it to redirect it to invoices page, use a filter. Then use an IF statement to compare length > 0, if 0 then just redirect to page. Might as well put a message error then too.

Upvotes: 0

Related Questions