Redirecting a user to another page after submitting a form

Hi All,

Currently, I have a view that essentially closes a lead, meaning that it simply copies the information from one table (leads) to another (deals), now what I really would like to do is that after clicking close, the user is redirected to another page where the user can update some entries (sales forecast), I have a view that updates the lead, so I thought that I can do something like below:

# This function closes the Lead

@login_required
def close_lead(request):
    if request.method == 'POST':
        deal_form = NewDealForm(request.POST)
        if deal_form.is_valid():
            deal_form.save()
            messages.success(request, 'You have successfully updated the status from open to Close')
            id = request.GET.get('project_id', '')
            obj = Leads.objects.get(project_id=id)
            obj.status = "Closed"
            obj.save(update_fields=['status'])
            ## Changing the Forecast Table Entry
            forecast = LeadEntry.objects.filter(lead_id=id)
            for i in forecast:
                m = i
                m.stage = "Deal"
                m.save(update_fields=['stage'])
            
            **update_forecast(request,id) ## Calls the function update_forecast**
            
            return HttpResponseRedirect(reverse('dashboard'))
        else:
            messages.error(request, 'Error updating your Form')
    else:
        id = request.GET.get('project_id', '')
        keys = Leads.objects.select_related().get(project_id=id)
        form_dict = {'project_id': keys.project_id,
                     'agent': keys.agent,
                     'client': keys.point_of_contact,
                     'company': keys.company,
                     'service': keys.services,
                     'licenses': keys.expected_licenses,
                     'country_d': keys.country
                     }

        form = NewDealForm(request.POST or None,initial=form_dict)        
    return render(request,
                  "account/close_lead.html",
                  {'form': form})

This view provides the formset that I want to update after closing the lead

@login_required
def update_forecast(request,lead_id):
    # Gets the lead queryset
    lead = get_object_or_404(Leads,pk=lead_id)
    #Create an inline formset using Leads the parent model and LeadEntry the child model
    FormSet = inlineformset_factory(Leads,LeadEntry,form=LeadUpdateForm,extra=0)
    if request.method == "POST":
        formset = FormSet(request.POST,instance=lead)
        if formset.is_valid():
            formset.save()
            return redirect('forecast_lead_update',lead_id=lead.project_id)

    else:
        formset = FormSet(instance=lead)

    context = {
                'formset':formset
               }
    return render(request,"account/leadentry_update.html",context)

As you can see I’m calling this function update_forecast(request,id) after validating the data in the form, and I would have expected to be somehow redirected to the .HTML page specified on that function, however, after clicking submit, the form from the first view is validated but then I.m redirected to dashboard.

My question how can I leverage existing functions in my views?, obviously, I will imagine that following the DRY principles you can do that in Django, so what am I doing wrong ?, howe can I call an existing function within another function in views?

Regards,

The render function returns an HttpResponse object, it doesn’t send you anywhere.

You’re calling update_forecast, which is returning your HttpResponse, but you’re throwing that response away. Instead, you’re returning an HttpResponseRedirect from your view, which is sending you to the url named dashboard.

Ken,

Thanks, I supposed that the way to do it is to use :

return HttpResponseRedirect(reverse('dashboard'))

And redirect the user, now if use the URL:

path('<lead_id>/update_forecast/', views.update_forecast,name='forecast_lead_update')

How do I attach the <lead_id> to the URL when using reverse?

You’ve lost me. I thought the problem was that you were trying to return the rendered result from account/leadentry_update.html?

What then is the issue you’re trying to address and what is the desired result?

Ken,

Essentially, I want to do this:

django - Can I call a view from within another view? - Stack Overflow

The short answer is yes. You’ve already done that in the code you posted earlier.

Keep in mind, a view is just a Python function that takes an HttpRequest as input and returns an HttpResponse as output. There’s nothing special about it in Python terms.

What I’m not clear on is whether you are clear on what the functions are doing and how to handle what’s being returned from each. Or, more specifically, what it is you’re looking to return from the view.

Ken,

Exactly, is not clear to me yet how to handle the views to achieve my desired outcome

Essentially, the first view (close_lead) has a form, and after the user submits the form, what I wanted to do is to call the function update_forecast, so I thought if I call the function after the form is submitted, the user will be then prompted with the other form which is rendered on “account/leadentry_update.html”, after that the user will be able to update a particular table, and then hit submit and that’s it.

Now when I call the function in close_lead:
update_forecast(request,id)

I get nothing but now is clear that the function I’m calling is taking a request but is not returning an HttpResponse but a request

Ok, so there’s a terminology issue here.

You’re not “calling a view from another view” - that’s not part of this at all.

In the normal processing of a form, a successful form submission redirects you to another page, which can then be another form.

So, in general terms, the first request for Page 1 renders a form. The user fills out the form and clicks submit. If the form is valid, data can be saved and the form redirects you to another view. That HttpRedirect is returned to the user at that point. The redirect is to be for the url for Page 2. The browser then issues the get for Page 2, which is then handled (again) like any other form-based page.