Search code examples
htmldjangodjango-templatesblock

Use multiple block and views in django templates


I am new to django, and I see that you could create templates that you could populate in views. You could also create some basic.htm that everyone extends...

Let say I have two pages: (django demo)

  • List of all questions
  • Detail of the question.

Now I would like to create "one page" that have first view as sidebar and another as a "detail- right" view.

I would like that on clicking on the list in sidebar change right vies.

It would be nice, if I could use different views (inside views.py) for loading separate templates.

I wish for base html would be something like this :

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Makro Zadravec</title>
    {% load staticfiles %}
    <link rel="stylesheet" type="text/css" href="{% static 'demo/css/bootstrap.min.css.css' %}" />
</head>
<body class="body" style="background-color: #f6f6f6">
    <div>
        <h1> This is title</h1>
    </div>
    <div>
        {% block sidebar %}

        {% endblock %}
    </div>
    <div>
        {% block content %}
        {% endblock %}
    </div>
</body>
</html> 

And then I would have template for blocks:

  • content
  • sidebar

in separate views.


Solution

  • Apart from styling here is the logic you can follow this

    as you said you already have template which already loaded list of question then your base view would return all the question object as queryset.

    First of all, you don't need to write separate template because you can handle this

    {% block content %}
       // this will load list of all question
    {% endblock %}
    {% block detail %}
       // here display detail of question
    {% endblock %}
    

    create two urls to hit one without kwargs and other with kwargs (if you use django version < 2.0 you need to use url instead of path)

    path('target/', QuestionView.as_view(), name='target-list'),
    path('target/<int:pk>', QuestionView.as_view(), name='target-detail')
    

    Now in view file you just need to handle the kwargs:

    class QuestionView(TemplateView):
         template_name = "template.html"
         model = Question
    
         def get_context_data(self, **kwargs):
            context = super(QuestionView, self).get_context_data(**kwargs)
            context['question_list'] = #your queryset to list question#
            pk = kwargs.get('pk', None)  # this will return pk (id of question) if hit url otherwise None
            if pk:
                context['question_detail'] = #your queryset to get question-detial# 
            return context
    

    so if you hit url with kwargs it will return both list of question and detail with it as context in template which you can access as below:

    {% block content %}
        # access question_list to list out all question
    {% endblock %}
    
    {% block detial %}
        {% if question_detail %}  // if question_detail context passed from view
            # add detail of question by accessing question_detail
        {% endif %}
    {% endblock %}