Escher
Escher

Reputation: 5776

Avoid recreating the GET logic in the POST part of a view

How can I avoid duplicating the logic code from the GET block in the view below?

The logic is view-specific enough that I don't feel it makes sense to put a helper function in a separate utils.py.

'''
show_stuff view shows different stuff depending on how many other 
POST requests have been submitted to view and saved to the DB.
All the users access the same URL randomly, so I don't believe it's possible to
split things up like "view_for_template1", "view_for_template2" in urls.py
'''
def show_stuff(request, url_dispatch_var1, url_dispatch_var2=None):
    if request.method == "GET":
        #30 lines of logic determining which Template and Context to return
    if request.method =="POST":
        #10 lines of logic determining which Form type to save
        #then, the same 30 lines of logic as the GET block to determine 
        #which Template and Context to return

Upvotes: 1

Views: 40

Answers (2)

pgrzesik
pgrzesik

Reputation: 2427

Maybe instead of returning body for POST request you could redirect user to your GET view ?

Upvotes: 0

Alasdair
Alasdair

Reputation: 308939

You can usually do something like the following:

def show_stuff(request, url_dispatch_var1, url_dispatch_var2=None):
    if request.method =="POST":
        #10 lines of logic determining which Form type to save
        # redirect if form is valid
    else:
        # this is a GET request
        form = MyForm() # unbound form for get request 
    # 30 lines of logic to determine which Template and Context to return
    return render(request, template, context)

Note that after a successful post request, the usual approach is to redirect to prevent duplicate submissions.

This might be a case where class based views are useful. You could subclass FormView, then override get_context_data, get_template_names and so on.

Upvotes: 3

Related Questions