Using context in view o pass common HTML items for reuse

I have a template, call layout, that is a common header for 10 or so pages. The only thing that changes is the color of one visual, based on the page you are on. I created the layout page which gets all the txt from the SQL DB. Works fine, however if I then try to extend it, none of the text appears, only the background graphics, unless I add the context to the page that extends layout. That seems to be repetitive, as well if I change any item in the header I need to do so over multiple pages. Ideally, all the context would be passed via layout, with any changes done in the individual page templates.

HTML Templates

Layout

{% load static %}

<!DOCTYPE html>
<html lang = "en">
<meta name="viewport" content="width=device-width, initial-scale=1">
<head>
    <link rel="stylesheet" href="{% static 'css/styles.css' %}">
    <title>{{ browsertab }}</title>
</head>
<body>
    <h1>{{ dashboard_title }}</h1>

    <div class="container" style="top: 5%;">
    
        <div class="item_LoO_Name">
          <div class="t1">{{ project }}</div>
          <div class="t2">{{ projecttext }}</div>
        </div>
        <div class="space"></div>
        <div class="item_context">{{ area.0 }}</div>
        <div class="space"></div>
        <div class="item_leadership">{{ area.1 }}</div>
        <div class="space"></div>
        <div class="item_policy" >{{ area.2 }}</div>
        <div class="space"></div>
        <div class="item_planning">{{ area.3 }}</div>
        <div class="space"></div>
        <div class="item_support">{{ area.4 }}</div>
        <div class="space"></div>
        <div class="item_operation">{{ area.5 }}</div>
        <div class="space"></div>
        <div class="item_management">{{ area.6 }}</div>
        <div class="space"></div>
        <div class="item_improvement">{{ area.7 }}</div>
        <div class="space"></div>
        <div class="triangle-right"></div>
        <div class="spaceblank"></div>
    
        
        <div class="item_LoO_Name" style="background-color: white; color: black;">
          <div class="t1">{{outcome}}</div>
          <div class="t3">{{ outcometext }}</div>
        </div>
    </div> 
    <br>  
    <p class="t1">{{ areaheader }}</p>
    {% block content %}
    {% endblock %}
</body>
</html>

leadership

{% extends "ISO22301/layout.html" %}

{% block content %}
    <style>
    div.item_leadership {
        background-color: rgb(211,211,211);
    }
    </style>
    <form action = "" method = "POST">
    {% csrf_token %}

    </form>

{% endblock %}

views.py

def layout(request):

# all the stuff to create context that is in leadership  was initially here 

    return render(request, "ISO22301/layout.html",)

def leadership(request):
    area=Area.objects.all() # get names of areas for header flow diagram
    #Name of browser tab
    browsertab=list(Dashboard.objects.values_list('company', flat=True))
    browsertab=browsertab[0]
        #Name of dashboard
    dashboard_title=list(Dashboard.objects.values_list('dashboard', flat=True))
    dashboard_title=dashboard_title[0]
    # names and text for both ends of LoO
    project=list(Project.objects.values_list('project', flat=True))
    projecttext=list(Project.objects.values_list('project_text', flat=True))
    outcome=list(Project.objects.values_list('outcome', flat=True))
    outcometext=list(Project.objects.values_list('outcome_text', flat=True))
    project=project[0]
    projecttext=projecttext[0]
    outcome=outcome[0]
    outcometext=outcometext[0]
    areaheader=Area_Header.objects.all() # get names of areas for header
    header=areaheader[1]
    print(areaheader)
    context = {
        "area": area,
        "areaheader": header,
        "browsertab": browsertab,
        "dashboard_title": dashboard_title,
        "project": project,
        "projecttext": projecttext,
        "outcome": outcome,
        "outcometext": outcometext,
    }
    return render(request, "ISO22301/leadership.html", context)

You’ve got a couple of different options. Depending upon exactly what it is that needs to be done, one option would be a custom context processor. (Note, there’s no direct way to pass data from a view into a context processor, you’d need to use some kind of common store (database, cache, session, etc) to make data from the view available to the processor.)

See Writing your own context processors for more details on this.

Thanks. Will use authentication

A couple of follow ons:

  1. I assume a user filling in the form with name, email, pw, etc. does not log them in, so I should start with the login page, have a “New User click here” that redirects to the user info page, and then redirect to the login. Alternatively, I could set them up as a user in admin and send them their login info.

  2. When I added the password field I had to set a default as even though there were no users it required it to avoid a Null field error. I removed it after migrating and then remigrated its no issues. Is this the normal way to do this. Other models exhibit the same behavior even in null=True is set.

password = models.CharField(max_length=30, default="password")

When the user submits a form, the form data is passed to a view.

What that view does, is up to the author of that view. If you want that submission to both create the user and log them in at the same time, you can do that.

Or, you can do as you describe. Or, you can do it pretty much any other way you wish. (For example, I once did a system that the person would register on their site. The site sent them an email with a link. Clicking on that link would connect them to the site with an authenticated session.)

Normally, the makemigrations command gives you the option to enter the default value for the migration. You can pretty much put anything valid in there if there are no existing rows. That way you don’t need to edit the model for this. (I believe there are some circumstances where that doesn’t work, but I can’t think of the last time I encountered one.)

Thanks, makes sense. Given at first there will be a small select user set I may just enter them in admin to make it easier for the user.

I saw where make migrations gave me the option but never liked what I tried, said it wasn’t valid python. I simply was entering some text, with no other code.

For something like the password field as you described in your earlier post, you should have been able to enter a literal string: "password".

Correct. If it’s a valid string literal, that should work. If you then examine the migration file created from that, Django creates a valid python statement from what you enter.

Ah, my mistake - I used password instead of “password”

Thanks