Dear Community,
I would like to display a full html content as response of POST request of an API made in the views.py.
The response is a full HTML document like
b'<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>leaflet</title> <script>(function() { // If window.HTMLWidgets is already defined, then use it; otherwise create a // new object. This allows preceding code to set options that affect the //
This is my views.py
from django.shortcuts import render
from django.contrib.gis.geos import GEOSGeometry
import json
import requests
# Create your views here.
from field.models import Field
def satelliteview(request):
if request.method=="POST":
pass
else:
user_fields=Field.objects.filter(User_id=request.user.id)
print(user_fields)
user_fields=user_fields.first()
print(user_fields)
geojson=user_fields.Field
geojson_feature = json.loads(GEOSGeometry(geojson, srid=4326).json)
print(geojson_feature)
API_endpoint="http://127.0.0.1:3000/AFS/htmlwidget?"
auth_data = {
"username": "XXXXXXXXXXXXXXXX",
"password": "XXXXXXXXXXXXXXXX"
}
response = requests.post(API_endpoint,
json=geojson_feature,
auth=(auth_data["username"],
auth_data["password"]))
print(response)
print(response.content)
context={
"response": response.content
}
return render(request, 'satellite/satellite.html', context=context)
This is my template
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load leaflet_tags %}
{% block content %}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% leaflet_js plugins="forms, geocoder, measurement" %}
{% leaflet_css plugins="forms, geocoder, measurement" %}
<title>New Field</title>
</head>
<body>
<p>ciao</p>
<iframe id="iframe" frameborder="0"></iframe>
<script>
document.getElementById('iframe').srcdoc = "{{response|safe}}";
</script>
</body>
</html>
{% endblock %}
This is my urls.py
from django.urls import path
from .views import satelliteview
urlpatterns = [
path("satellite/", satelliteview, name="satellite"),
]
and this is the result
How can i display the html widget proprely?
My guess is that you’re passing the data as bytes, since this is the type of the .content
member on the Response class. You probably are trying to access the .text
member instead.
[I don’t know if this is the optimal solution, or if you should by doing it this way… but it may work]
Cheers
Thanks to reply @leandrodesouzadev,
I have changed the .content to .text of the views.py but still i have got problem to render the html as you see below
This is the views.py changed with your suggestion
from django.shortcuts import render
from django.contrib.gis.geos import GEOSGeometry
import json
import requests
# Create your views here.
from field.models import Field
def satelliteview(request):
if request.method=="POST":
pass
else:
user_fields=Field.objects.filter(User_id=request.user.id)
print(user_fields)
user_fields=user_fields.first()
print(user_fields)
geojson=user_fields.Field
geojson_feature = json.loads(GEOSGeometry(geojson, srid=4326).json)
print(geojson_feature)
API_endpoint="http://127.0.0.1:3000/AFS/htmlwidget?"
auth_data = {
"username": "XXXXXXXXXXXXXXXX",
"password": "XXXXXXXXXXXXXXXX"
}
response = requests.post(API_endpoint,
json=geojson_feature,
auth=(auth_data["username"],
auth_data["password"]))
print(response)
print(response.text)
context={
"response": response.text
}
return render(request, 'satellite/satellite.html', context=context)
I have tried to use your suggestion response.text
in the template but in this way
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load leaflet_tags %}
{% block content %}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% leaflet_js plugins="forms, geocoder, measurement" %}
{% leaflet_css plugins="forms, geocoder, measurement" %}
<title>New Field</title>
</head>
<body>
<p>ciao</p>
<div>
{{response|safe}}
</div>
<p>ciao</p>
</body>
</html>
{% endblock %}
This is the results
and now render but cover the entire page and both p tag disappear. How can i isolate the html content and display both p tags?
That’s happening because you’re putting the entire html from the response into your HTML.
If you’re following a tutorial, you better double check what’s different from what you’re doing.
Actually i am not following a tutorial.
I am trying to figure out how to insert a HTML document produced by a post request inside a HTML tag element in order to costumize the position and size.
Then you need that iframe.
I wonder if there’s any other JS or CSS required (in that iframe) in order to render the map correctly.
Thanks to reply.
The html widget have all the required imports to be rendered.
Now i have changed my code to this but still get problem.
views.py
from django.shortcuts import render
from django.contrib.gis.geos import GEOSGeometry
import json
import requests
# Create your views here.
from field.models import Field
def satelliteview(request):
if request.method=="POST":
pass
else:
user_fields=Field.objects.filter(User_id=request.user.id)
user_fields=user_fields.first()
geojson=user_fields.Field
geojson_feature = json.loads(GEOSGeometry(geojson, srid=4326).json)
API_endpoint="http://127.0.0.1:3000/AFS/Widget"
auth_data = {
"username": "XXXXXXX",
"password": "XXXXXXX"
}
response = requests.post(API_endpoint,
json=geojson_feature,
auth=(auth_data["username"],
auth_data["password"]))
response=response.text
print(response)
context={
"response": response
}
return render(request, 'satellite/satellite.html', context=context)
This is the template
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% load leaflet_tags %}
{% block content %}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>New Field</title>
{% leaflet_js %}
{% leaflet_css %}
</head>
<body>
<p>ciao</p>
<iframe srcdoc="{{ response|safe }}"></iframe>
<script>
document.getElementById('iframe').srcdoc = "{{response|safe}}";
</script>
<p>ciao</p>
</body>
</html>
{% endblock %}
This is my result
I have opened the console of my browser and i have got the following issues:
dataTables.bootstrap5.min.js:11 Uncaught ReferenceError: jQuery is not defined
at dataTables.bootstrap5.min.js:11:283
at dataTables.bootstrap5.min.js:11:308
(anonymous) @ dataTables.bootstrap5.min.js:11
(anonymous) @ dataTables.bootstrap5.min.js:11
VM452:2 Uncaught SyntaxError: Invalid or unexpected token (at VM452:2:52)
VM459:615 Uncaught TypeError: Cannot read properties of undefined (reading 'widget')
at 13../cluster-layer-store (VM459:615:26)
at o (VM459:1:265)
at r (VM459:1:431)
at VM459:1:460
When i use the following template code
{% autoescape off %}
{{ response }}
{% endautoescape %}
the html document render but again cover the entire page.
See the results