[Django]-Django – two views, one page

21👍

A view in django is just any callable that ultimately returns a Response object. Within that view, you could split the work up into whatever organization suits you. Maybe your view 100% delegates out to other methods.

In your case, your main view would call 2 other functions for data. These could also be views if they also accept a Request object as well and make use of it. They also would need to return Response objects to be considered django views since that is how you would point URLs at them. But it doesn’t really do you any good to have two other views returning you Response objects. What you probably want is just other methods that do specific tasks and return some data structure, or maybe even a rendered snippet of a template. You would then use these data, or merge the template strings together and return that in your main Response.

If you are really set on making use of other views that return Response objects, then you can do something like grabbing the body out of them, and merging them into your own response:
https://docs.djangoproject.com/en/1.4/ref/request-response/

Really, nothing is much different from the tutorials. You are just calling other methods for data. If you want to make it organized you should separate the data processing logic from the view function. Your main view would call these data processing functions for values. And your “sub views” would just be simple views that also call these individual data functions and wrap them into a Response.

Pseudo:

def mainView(request):
    val = data1()
    val2 = data2()
    response = # val + va2 + other stuff
    return response

def subView1(request):
    val = data1()
    response = # val  + stuff
    return response 

def subView2(request):
    val2 = data2()
    response = # val2  + stuff
    return response 

def data1():
    val = # get data
    return val 

def data2():
    val2 = # get data
    return val2
👤jdi

20👍

The views should contain only view-related logic:

  • Views are for processing requests and serving the requested data
  • That includes checking for user authorization/permission and dealing with given parameters
  • If the requested data is not trivial to fetch, outsource the code to a more appropriate location (your model or form definitions or another custom place)

Outsource calculations to make them reusable and call these methods from your views to keep them small.

Nevertheless, maybe you want something else, namely templates with extends and include.

With extends you are able to create a base layout for your HTML code and define specific blocks which can be rendered elsewhere. Example? Ok.

base.html:

<!doctype html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>{% block title %}My Site{% endblock %}</title>
    </head>
    <body>
        <div id="header">
            <h1>My Site</h1>
        </div>
        {% block content %}{% endblock %}
    </body>
</html>

Then, in any other template, you can overwrite the blocks title and content which we defined in the base template:

{% extends "base.html" %}

{% block title %}My Page{% endblock %}

{% block content %}
<h2>My Page</h2>
<div>lorem ipsum</div>
{% endblock %}

Also, you can create sub-templates like the following one, let’s name it _item.html:

<li class="item">
  <span>{{ something.foo }}</span>
  <strong>{{ something.bar }}</span>
</li>

You can include that snippet in any other template and pass an arbitrary number of parameters:

{% for something in mymodel.mym2mrelation.all %}
    {% include "_item.html" with something=something only %}
{% endfor %}

Naturally, you can combine both concepts. Like so:

{% extends "base.html" %}

{% block title %}My Page{% endblock %}

{% block content %}
<h2>My Page</h2>
<div>lorem ipsum</div>
<ul>
{% for something in mymodel.mym2mrelation.all %}
    {% include "_item.html" with something=something only %}
{% endfor %}
</ul>
{% endblock %}

I hope that helps.

👤Alp

10👍

This is the perfect time to introduce class based views.

class methods are essentially “sub views” that split logic into reusable snippets.

If you want the readability of split functions – it only gets better by using django’s class based views (via all of the functionality provided by default and access to request, kwargs, args, etc., via the class instance).

The docs even contain a good example for returning a JSON response or HTML response based on request parameters (this exact situation).

The best part? You can reuse your class based views as mixins in future views. Look at the docs example to see how to convert any class based view to handle a JSON response of the template context via a simple subclass.

Leave a comment