Sunday, August 30, 2015

How to make one view do the work of two

Hey folks! Today's is an interesting topic: making one view do two functions. In fact, you can make it do more than two; you an make them do 8 at a time. Think of it as view overloading, if you're into that kind of thing.
So let's dive into it.

Take logging into your account for example. Initially what I used to do is split this process into three views: one for displaying the login page, one for verification of credentials, and a third for displaying the profile. With the new method I will outline in this post you can do that using only two views rather than three. We'll combine displaying the login page and credential verification into one view. The way well do that will use HTTP request methods. Let's see what those are (going to take a little help from TutorialsPoint for the exact definitions):

  1. GET: This method is used to extract data that is embedded in the URL. The data is identified by a '?'. For example, in the URL "http://some.url/?data1=value1&data2=value2" the data after the '?' can be translated as {'data1':'value1', 'data2':'value2'}
  2. HEAD: This one is the same as GET, but this one only transfers status line and header section
  3. POST: This method sends data directly to the server rather than embedding it in the URL. It is used for handling sensitive data like passwords and credit card numbers. That way, when a user enters it in the browser, it cannot be seen by someone standing behind him
  4. PUT: This is an upload based method. The representations of target resource are replaced with uploaded content
  5. DELETE: As the name indicates, this method deletes all representations of the target resource
  6. CONNECT: Establishes a connection with the server
  7. OPTIONS: Describes communication options for target resource
  8. TRACE: Performs a loopback test on connection tunnel
Now each webpage can be accessed using one of those methods. you can overload a view by using an if  block to see what access method is used and do a different thing based on that.

def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == "POST":
        # code to authenticate user

As you can see, in this case, if the request method is GET, which it is by default, it'll just render the login page. Normally, in the login form the action will be POST since we'll be asking for passwords. So the first page will be rendered due to the GET method and the verification will be done by the POST method. So this way you can overload views.
That's all for today folks!

4 comments:

  1. Django has some cool stuff built in. Instead of an if block you could do:

    from django.views.generic import View

    class TestView(View):

    def post(self, request, *args, **kwargs):
    pass

    def post(self, request, *args, **kwargs):
    pass

    def patch(self, request, *args, **kwargs):
    pass

    There's more info here https://docs.djangoproject.com/en/1.8/ref/class-based-views/base/#django.views.generic.base.View.http_method_names

    Hope that's helpful

    ReplyDelete
    Replies
    1. Oh yeah that was going to be my next post :P Just wanted to introduce the users to this before going on to class based views.

      Delete
  2. Restricting the semantic difference between GET and POST to just "hiding sensitive data" is just plain nonsense... And branching on the http method is really nothing new, you'll find this pattern in just every Django tutorial.

    ReplyDelete