diff --git a/PROD_EXPORT_FINAL.sqlite b/PROD_EXPORT_FINAL.sqlite new file mode 100644 index 00000000..9bb13553 Binary files /dev/null and b/PROD_EXPORT_FINAL.sqlite differ diff --git a/benchmarks/templates/benchmarks/model.html b/benchmarks/templates/benchmarks/model.html index 5ef463e6..d8bd8ed5 100644 --- a/benchmarks/templates/benchmarks/model.html +++ b/benchmarks/templates/benchmarks/model.html @@ -154,6 +154,19 @@

Anonymous Model #{{ model.id }}

{{ visual_degrees }} degrees + +
+
+ +
+ Shift-click layers to view metadata. +
+
+
+ + {% endblock %} @@ -287,6 +300,10 @@

Scores on benchmarks

+ + {% include "benchmarks/model_visual.html" with model_architecture=model_architecture %} + + {# Usage #}

diff --git a/benchmarks/templates/benchmarks/model_visual.html b/benchmarks/templates/benchmarks/model_visual.html new file mode 100644 index 00000000..43da34aa --- /dev/null +++ b/benchmarks/templates/benchmarks/model_visual.html @@ -0,0 +1,45 @@ +{% load static %} + + + + + + Model Visualization - {{ model.id }} + + + + + + + +

Model Architecture Visualization (Model ID: {{ model.id }})

+ +
+ +
+ + + + + + {{ visualization_metadata|json_script:"layers-json" }} + + + + + + + + + + + + + diff --git a/benchmarks/views/extract_model_architecture.py b/benchmarks/views/extract_model_architecture.py new file mode 100644 index 00000000..2edb9d37 --- /dev/null +++ b/benchmarks/views/extract_model_architecture.py @@ -0,0 +1,131 @@ +# import json +# import os +# import torch +# from torchsummary import summary +# from io import StringIO +# from contextlib import redirect_stdout +# +# # Directory where model JSON files will be stored +# ARCHITECTURE_JSON_DIR = "static/model_architecture_json/" +# +# +# def extract_trainable_layers(model, model_id): +# """ +# Extracts trainable layers from a PyTorch model and saves them as a JSON file. +# - Trainable layers are those where `Param # != 0` +# - Uses `torchsummary.summary()` to get layer details. +# """ +# os.makedirs(ARCHITECTURE_JSON_DIR, exist_ok=True) +# +# # Redirect torchsummary output to a string buffer +# buffer = StringIO() +# with redirect_stdout(buffer): +# summary(model, input_size=(3, 224, 224)) # Assuming an image model with 3x224x224 input +# +# output = buffer.getvalue() +# lines = output.split("\n") # Convert output to lines +# +# model_params = { +# "Visualization-Layer-Parameters": {} +# } +# +# # Process each line and extract Layer Type, Output Shape, and Param # +# for line in lines[3:]: # Skip the header +# parts = line.split() +# if len(parts) < 4: # Ignore invalid lines +# continue +# +# layer_name = parts[0] # First column is Layer Type +# param_count = parts[-1] # Last column is Param # +# +# try: +# param_count = int(param_count) # Convert to integer +# except ValueError: +# continue # Skip if it's not a number +# +# if param_count > 0: # **Only keep trainable layers** +# model_params["Visualization-Layer-Parameters"][layer_name] = [param_count, param_count + 5] # Example range +# +# # Define JSON file path +# json_file_path = os.path.join(ARCHITECTURE_JSON_DIR, f"model_{model_id}.json") +# +# # Save JSON data +# with open(json_file_path, "w") as json_file: +# json.dump(model_params, json_file, indent=4) +# +# print(f"Model architecture saved at: {json_file_path}") +# +# +# if __name__ == "__main__": +# # Example: Use a pre-trained ResNet model for testing +# model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True) +# extract_trainable_layers(model, model_id="resnet50") + +import json +import os +import torch +from torchsummary import summary +from io import StringIO +from contextlib import redirect_stdout + +ARCHITECTURE_JSON_DIR = "static/model_architecture_json/" + +import json +import os +import torch +from torchsummary import summary +from io import StringIO +from contextlib import redirect_stdout + +ARCHITECTURE_JSON_DIR = "static/model_architecture_json/" + + +def extract_model_parameters(model, model_id): + """ + Extracts model layer details (Layer Name, Output Shape, Param #) and saves as JSON. + """ + os.makedirs(ARCHITECTURE_JSON_DIR, exist_ok=True) + + model_params = {"layers": []} + + buffer = StringIO() + with redirect_stdout(buffer): + summary(model, input_size=(3, 224, 224)) + + output = buffer.getvalue() + lines = output.split("\n") + + for line in lines[3:]: + parts = line.split() + if len(parts) < 4: + continue + + print(parts) + layer_name = parts[0] + output_shape = parts[1] + param_count = parts[-1] + + try: + param_count = int(param_count) + except ValueError: + continue + + model_params["layers"].append({ + "layer_name": layer_name, + "output_shape": output_shape, + "param_count": param_count + }) + + + json_file_path = os.path.join(ARCHITECTURE_JSON_DIR, f"model_{model_id}.json") + + with open(json_file_path, "w") as json_file: + json.dump(model_params, json_file, indent=4) + + print(f"✅ Model architecture saved at: {json_file_path}") + print(json.dumps(model_params, indent=4)) + + +if __name__ == "__main__": + model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True) + extract_model_parameters(model, model_id="1226") diff --git a/benchmarks/views/index.py b/benchmarks/views/index.py index 66ffb88e..3da3aad5 100644 --- a/benchmarks/views/index.py +++ b/benchmarks/views/index.py @@ -99,6 +99,7 @@ def view(request, domain: str): leaderboard_context = get_context(domain=domain) return render(request, 'benchmarks/leaderboard/leaderboard.html', leaderboard_context) + # get_context is used for both leaderboard and model views. We can cache the results of it so that after the first # request, the cached results is served faster @cache_get_context() @@ -192,7 +193,7 @@ def get_context(user=None, domain: str = "vision", benchmark_filter=None, model_ 'citation_domain_url': citation_domain_url, 'citation_domain_title': citation_domain_title, 'citation_domain_bibtex': citation_domain_bibtex, - 'csv_downloadable': csv_data + 'csv_downloadable': csv_data, } diff --git a/benchmarks/views/model.py b/benchmarks/views/model.py index 6cc2a7d1..2c735253 100644 --- a/benchmarks/views/model.py +++ b/benchmarks/views/model.py @@ -10,8 +10,17 @@ from .index import get_context from ..models import BenchmarkType, Model +# FOR DUMMY VISUALIZATION # +import json +import os + + + + _logger = logging.getLogger(__name__) +# Load JSON file for model architecture visualization +ARCHITECTURE_JSON_DIR = "static/model_architecture_json/" def view(request, id: int, domain: str): model, model_context, reference_context = determine_context(id, request, domain) @@ -31,12 +40,29 @@ def view(request, id: int, domain: str): layers = get_layers(model) model_context['layers'] = layers + # _logger.info(f"Extracted Layers Data: {json.dumps(layers, indent=4)}") + + DUMMY_LAYERS_FILE = os.path.join(ARCHITECTURE_JSON_DIR, "dummy_layers.json") + + # Add Visualization-Layer-Parameters to model_context + if os.path.exists(DUMMY_LAYERS_FILE): + with open(DUMMY_LAYERS_FILE, 'r') as f: + dummy_layers_data = json.load(f) + + model_context['visualization_metadata'] = dummy_layers_data # Store full JSON + + if "Visualization-Layer-Parameters" in dummy_layers_data: + vis_layers = dummy_layers_data["Visualization-Layer-Parameters"] + model_context['visualization_layers'] = vis_layers + + # only show detailed model info to superuser or owner: if request.user.is_superuser or model.user.id == request.user.id: model_context['submission_details_visible'] = True return render(request, 'benchmarks/model.html', model_context) + def determine_context(id, request, domain: str): # this is a bit hacky: we're loading scores for *all* public models as well as *all* of the user's models # so we're loading a lot of unnecessary detail. But it lets us re-use already existing code. diff --git a/requirements.txt b/requirements.txt index b2e29111..c553eb10 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ asgiref==3.7.2 -backports.zoneinfo==0.2.1 boto3==1.28.15 botocore==1.31.15 certifi==2023.7.22 diff --git a/static/benchmarks/js/draw_layers.js b/static/benchmarks/js/draw_layers.js new file mode 100644 index 00000000..ecf663a3 --- /dev/null +++ b/static/benchmarks/js/draw_layers.js @@ -0,0 +1,368 @@ +// draw_layers.js +// Author: Aneesa Beckford +// Description: +// Renders interactive 3D-like dummy layer blocks and connections in an SVG with zoom and pan support. +// Users can click or shift-click on layers to view metadata and highlight different components + +// Keeps track of which rectangle is currently highlighted +let currentlyHighlightedRect = null; + +// Create the main SVG container and a zoomable group inside it +const svg = d3.select("svg"); +const zoomGroup = svg.append("g").attr("class", "zoom-group") + +// Set up zoom & pan behavior +const zoom = d3.zoom() + .scaleExtent([0.5, 5]) + .on("zoom", (event) => { + zoomGroup.attr("transform", event.transform) + }); + +svg.call(zoom) + +let selectedLayers = []; +let currentlyShownLayer = null; + +// Load & parse the JSON data injected into the DOM +const raw = document.getElementById("layers-json"); +if (!raw) { + console.error("layers-json not found!"); +} + +const allData = JSON.parse(document.getElementById('layers-json').textContent); + +// Extract different sections from the parsed JSON +const regionData = allData["Region"] || {}; +const descriptionData = allData["Visualization-Description"] || {}; + +// Returns true if the given layer name exists in regionData +function regionHasLayer(layerName) { + return Object.values(regionData).includes(layerName); +} + +/** + * Displays a floating box with metadata for the clicked layer. + * Highlights the selected rectangle and positions the tooltip + * @param layerName + * @param event + * @param groupElement + */ +function showLayerMetadata(layerName, event, groupElement) { + const box = document.getElementById("layer-info-box"); + if (!box) return; + + if (currentlyHighlightedRect) { + currentlyHighlightedRect.select(".front-face") + .attr("stroke", "black") + .style("filter", "drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.4))"); + currentlyHighlightedRect.select(".side-face") + .attr("stroke", "black"); + } + groupElement.select(".front-face") + .attr("stroke", "blue") + .style("filter", "drop-shadow(2px 2px 2px rgba(66, 135, 245, 0.8))"); + + groupElement.select(".side-face") + .attr("stroke", "blue") + .style("filter", "drop-shadow(2px 2px 2px rgba(66, 135, 245, 0.8))"); + + currentlyHighlightedRect = groupElement; + + const metadata = descriptionData[layerName]?.metadata; + + if (metadata) { + let html = `Layer: ${layerName}
`; + for (const [key, value] of Object.entries(metadata)) { + html += `${key}: ${value}
`; + } + box.innerHTML = html; + } else { + box.innerHTML = `${layerName}
No metadata available.`; + } + + // Position the tooltip + const svgRect = svg.node().getBoundingClientRect(); + + box.style.left = `${event.clientX + 10}px`; + box.style.top = `${svgRect.top + 320}px`; + box.style.display = 'block'; + + currentlyShownLayer = layerName; +} + +/** + * Renders the list of metadata for all shift-clicked (selected) layers + * in the side panel under "Selected Layers" + */ +function renderSelectedMetadataBox() { + const container = document.getElementById("selected-metadata-content"); + const title = document.getElementById("selected-metadata-title"); + + if (!container || !title) return; + + if (selectedLayers.length === 0) { + container.innerHTML = "Shift-click layers to view metadata."; + title.style.display = "none"; + return; + } + + title.style.display = "block"; + + let html = ""; + container.innerHTML = html; +} + + +const layersData = allData["Visualization-Layer-Parameters"] || {}; +const connectionData = allData["Visualization-Connections"] || []; + +// Layout constants +const xStart = 50; +const yMid = 300; +const spacing = 30; + +//Scaling factors for converting width/height to screen pixels +const widthScale = 5; +const heightScale = 3; + +let x = xStart; + +let layerIndex = 0; + +const layerPositions = {}; +const layerOrder = {}; + +// Render each layer as a 3D-styled rectangle with depth (front, top, side) +Object.entries(layersData).forEach(([layerName, values]) => { + if (!Array.isArray(values)) return; + + const [w, h] = values; + const rectWidth = Math.max(20, w * widthScale); + const rectHeight = Math.max(20, h * heightScale); + const y = yMid - rectHeight / 2; + + // Track layer position and dimensions for drawing arrows later + layerPositions[layerName] = { + centerX: x + rectWidth / 2, + centerY: y + rectHeight / 2, + leftX: x, + rightX: x + rectWidth, + topY: y, + bottomY: y + rectHeight, + width: rectWidth, + height: rectHeight + }; + + layerOrder[layerName] = layerIndex; + layerIndex++; + + // Create a group to hold all parts of the layer block + const group = zoomGroup.append("g").attr("class", "layer-group"); + + const fillColor = regionHasLayer(layerName) ? "#F5FD66" : "rgb(7, 137, 48)"; + const depth = 12; + + // Add the front face of the rectangle + const front = group.append("rect") + .attr("x", x) + .attr("y", y) + .attr("width", rectWidth) + .attr("height", rectHeight) + .attr("fill", fillColor) + .attr("stroke", "black") + .attr("class", "front-face") + .style("cursor", "pointer") + .style("filter", "drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.4))") + .on("click", function (event) { + // Shift-click toggles selection for multi-layer metadata view + // Regular click selects only this layer and shows tooltip + if (event.shiftKey) { + // Prevent zoom behavior when shift-clicking on layer + if (!selectedLayers.includes(layerName)) { + selectedLayers.push(layerName); + } else { + selectedLayers = selectedLayers.filter(name => name !== layerName); + } + renderSelectedMetadataBox(); + } else { + selectedLayers = []; + renderSelectedMetadataBox(); + + // Reset all groups + svg.selectAll(".front-face") + .attr("stroke", "black") + .style("filter", "drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.4))"); + + showLayerMetadata(layerName, event, group); + } + if (event.shiftKey){ + event.preventDefault(); + event.stopImmediatePropagation(); + } else { + event.stopPropagation(); + } + }); + + // Add top face of the rectangle + group.append("polygon") + .attr("points", ` + ${x},${y} + ${x + depth},${y - depth} + ${x + rectWidth + depth},${y - depth} + ${x + rectWidth},${y} + `) + .attr("fill", d3.color(fillColor).darker(0.5)) + .attr("stroke", "black"); + + // Add side face of the rectangle + group.append("polygon") + .attr("class", "side-face") + .attr("points", ` + ${x + rectWidth},${y} + ${x + rectWidth + depth},${y - depth} + ${x + rectWidth + depth},${y + rectHeight - depth} + ${x + rectWidth},${y + rectHeight} + `) + .attr("fill", d3.color(fillColor).darker(1)) + .attr("stroke", "black"); + + + // Add a text label centered below each layer rectangle + zoomGroup.append("text") + .attr("x", x + rectWidth / 2) + .attr("y", y + rectHeight + 15) + .attr("text-anchor", "middle") + .attr("font-size", "12px") + .text(layerName); + + x += rectWidth + spacing; +}); + +// Add a marker for arrowheads +const defs = zoomGroup.append("defs"); + +defs.append("marker") + .attr("id", "arrow") + .attr("viewBox", "0 0 10 10") + .attr("refX", 10) + .attr("refY", 5) + .attr("markerWidth", 4) + .attr("markerHeight", 4) + .attr("orient", "auto") + .append("path") + .attr("d", "M 0 0 L 10 5 L 0 10 z") + .attr("fill", "black"); + +// Draw arrows representing connections between layers by iterating through all defined connections +connectionData.forEach(([source, target]) => { + const sourcePos = layerPositions[source]; + const targetPos = layerPositions[target]; + + if (!sourcePos || !targetPos) { + console.warn(`Skipping connection from ${source} to ${target} — missing position`); + return; + } + + // Draw a curved self-loop for recurrent layers + const isRecurrent = source === target; + if (isRecurrent) { + const box = sourcePos; + const loopWidth = box.width * 0.5; + const loopHeight = box.height * 1.5; + + const startX = box.rightX; + const startY = box.centerY; + const endX = box.leftX; + const endY = box.centerY; + + const pathData = ` + M ${startX} ${startY} + C ${startX + loopWidth} ${startY - loopHeight}, + ${endX - loopWidth} ${endY - loopHeight}, + ${endX} ${endY} + `; + + zoomGroup.append("path") + .attr("d", pathData) + .attr("fill", "none") + .attr("stroke", "black") + .attr("stroke-width", 2) + .attr("marker-end", "url(#arrow)"); + + } else { + // Draw a straight or curved connection between different layers + + const dx = targetPos.leftX - sourcePos.rightX; + const dy = targetPos.centerY - sourcePos.centerY; + + const startX = sourcePos.rightX; + const startY = sourcePos.centerY; + const endX = targetPos.leftX; + const endY = targetPos.centerY; + + const gap = targetPos.leftX - sourcePos.rightX; + const tolerance = 5; + const isAdjacent = Math.abs(gap - spacing) <= tolerance; + + let pathData; + if (isAdjacent) { + // Draw a straight line + pathData = ` + M ${startX} ${startY} + L ${endX} ${endY} + `; + } else { + // Draw a curved line + const curveHeight = Math.min(Math.abs(dx) * 0.2, 150); + + pathData = ` + M ${startX} ${startY} + C ${startX + dx / 3} ${startY - curveHeight}, + ${startX + 2 * dx / 3} ${endY - curveHeight}, + ${endX} ${endY} + `; + } + + zoomGroup.append("path") + .attr("d", pathData) + .attr("fill", "none") + .attr("stroke", "black") + .attr("stroke-width", 2) + .attr("marker-end", "url(#arrow)"); + } +}); + +// When clicking anywhere outside a layer, hide a tooltip and reset highlights +window.addEventListener("click", function () { + const box = document.getElementById("layer-info-box"); + if (box) box.style.display = "none"; + currentlyShownLayer = null; + + if (currentlyHighlightedRect) { + currentlyHighlightedRect.select(".front-face") + .attr("stroke", "black") + .style("filter", "drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.4))"); + + currentlyHighlightedRect.select(".side-face") + .attr("stroke", "black") + .style("filter", null); + + currentlyHighlightedRect = null; + } +}); + + + + + + + diff --git a/static/model_architecture_json/dummy_layers.json b/static/model_architecture_json/dummy_layers.json new file mode 100644 index 00000000..d3fcc4ba --- /dev/null +++ b/static/model_architecture_json/dummy_layers.json @@ -0,0 +1,60 @@ +{ + "Region": { + "V1": "layer2", + "V2": "layer4", + "V4": "layer5", + "IT": "layer8" + }, + "Visualization-Layer-Parameters": { + "layer1": [5, 10], + "layer2": [10, 15], + "layer3": [15, 20], + "layer4": [20, 25], + "layer5": [25, 30], + "layer6": [30, 35], + "layer7": [35, 40], + "layer8": [1, 100] + }, + "Visualization-Connections": [ + ["layer1", "layer2"], + ["layer2", "layer3"], + ["layer3", "layer4"], + ["layer4", "layer5"], + ["layer5", "layer6"], + ["layer6", "layer7"], + ["layer7", "layer8"], + ["layer3", "layer3"], + ["layer6", "layer2"] + ], + "Visualization-Description": { + "layer1": { + "metadata": { + "neurons": 2500, + "activation": "ReLU", + "inputDim": "25x100", + "outputDim": "25x100", + "description": "initial processing layer for visual features" + } + }, + "layer2": { + "metadata": { + "neurons": 3000, + "activation": "ReLU", + "inputDim": "25x100", + "outputDim": "20x80", + "description": "V1 area" + } + }, + "layer4": { + "metadata": { + "neurons": 4000, + "activation": "ReLU", + "inputDim": "20x80", + "outputDim": "15x60", + "description": "V2 area" + } + } + } +} + + diff --git a/web/settings.py b/web/settings.py index 5047a5bc..c9a5ca50 100644 --- a/web/settings.py +++ b/web/settings.py @@ -50,6 +50,7 @@ def get_secret(secret_name, region_name): if os.getenv("DJANGO_ENV") == 'development': hosts_list.append('127.0.0.1') hosts_list.append("brain-score-web-dev-updated.eba-e8pevjnc.us-east-2.elasticbeanstalk.com") # migrated dev site hosts_list.append("Brain-score-web-prod-updated.eba-e8pevjnc.us-east-2.elasticbeanstalk.com") # migrated prod site +hosts_list.append("127.0.0.1") ALLOWED_HOSTS = hosts_list # Allows E-mail use @@ -115,51 +116,51 @@ def get_secret(secret_name, region_name): # https://docs.djangoproject.com/en/2.0/ref/settings/#databases def get_db_info(): - if os.getenv("DJANGO_ENV") == "development": - from dotenv import load_dotenv; load_dotenv() - - return { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'dev', - 'USER': 'postgres', - 'PASSWORD': os.getenv('DB_PASSWORD'), - 'HOST': os.getenv('DB_HOST'), - 'PORT': '5432' - } + # if os.getenv("DJANGO_ENV") == "development": + # from dotenv import load_dotenv; load_dotenv() + # + # return { + # 'default': { + # 'ENGINE': 'django.db.backends.postgresql_psycopg2', + # 'NAME': 'dev', + # 'USER': 'postgres', + # 'PASSWORD': os.getenv('DB_PASSWORD'), + # 'HOST': os.getenv('DB_HOST'), + # 'PORT': '5432' + # } + # } + # db_secret_name = os.getenv("DB_CRED", "brainscore-1-ohio-cred-migrated") + # try: + # secrets = get_secret(db_secret_name, REGION_NAME) + # DATABASES = { + # 'default': { + # 'ENGINE': 'django.db.backends.postgresql_psycopg2', + # 'NAME': secrets["dbInstanceIdentifier"], + # 'USER': secrets["username"], + # 'PASSWORD': secrets["password"], + # 'HOST': secrets["host"], + # 'PORT': secrets["port"] + # } + # } + # except NoCredentialsError: + # if 'RDS_DB_NAME' in os.environ: # when deployed to AWS, use environment settings for database + # DATABASES = { + # 'default': { + # 'ENGINE': 'django.db.backends.postgresql_psycopg2', + # 'NAME': os.environ['RDS_DB_NAME'], + # 'USER': os.environ['RDS_USERNAME'], + # 'PASSWORD': os.environ['RDS_PASSWORD'], + # 'HOST': os.environ['RDS_HOSTNAME'], + # 'PORT': os.environ['RDS_PORT'], + # } + # } + # else: # for deployment, use local sqlite + DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'PROD_EXPORT_FINAL.sqlite'), } - db_secret_name = os.getenv("DB_CRED", "brainscore-1-ohio-cred-migrated") - try: - secrets = get_secret(db_secret_name, REGION_NAME) - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': secrets["dbInstanceIdentifier"], - 'USER': secrets["username"], - 'PASSWORD': secrets["password"], - 'HOST': secrets["host"], - 'PORT': secrets["port"] - } - } - except NoCredentialsError: - if 'RDS_DB_NAME' in os.environ: # when deployed to AWS, use environment settings for database - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': os.environ['RDS_DB_NAME'], - 'USER': os.environ['RDS_USERNAME'], - 'PASSWORD': os.environ['RDS_PASSWORD'], - 'HOST': os.environ['RDS_HOSTNAME'], - 'PORT': os.environ['RDS_PORT'], - } - } - else: # for deployment, use local sqlite - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } - } + } return DATABASES @@ -187,9 +188,9 @@ def get_db_info(): # https://docs.djangoproject.com/en/2.0/topics/i18n/ # Security settings for headers and cookies -SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') -SESSION_COOKIE_SECURE = True -CSRF_COOKIE_SECURE = True +# SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') +# SESSION_COOKIE_SECURE = True +# CSRF_COOKIE_SECURE = True LANGUAGE_CODE = 'en-us' @@ -200,7 +201,7 @@ def get_db_info(): USE_L10N = True -USE_TZ = True +#USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/