I'm new in Javascript and this is my html code that contain django template :
I have img element which src attribute is "{% static 'basic/myImage.jpg' %}" which actually django template to load static file
<img src="{% static 'basic/myImage.jpg' %}" alt="img"/>
then i have script (javascript) let say main.js which aim is to select that img src attribute which will return literally "{% static 'basic/myImage.jpg' %}"
var myImg = document.querySelector('img');
var myImgSrc = myImg.getAttribute('src'); //return a string "{% static 'basic/myImage.jpg' %}"
my problem is when i try equality test in web console (inspecting element) :
myImgSrc === "{% static 'basic/myImage.jpg' %}" is return false
may be there is escape character or special character to represent my django template, can someone explain how to represent django template in literal js string. Thank you sorry for my bad english.
It's hard to tell exactly what you are trying to do, but I'll attempt to offer some suggestions.
When the template is rendered, {% static 'basic/myImage.jpg' %} is also rendered, so it becomes "/static/app/images/basic/myImage.jpg" or whatever. So your javascript evaluation will always be false.
If you need javascript to have the actual value returned by {% static 'basic/myImage.jpg' %}, then you will need to include the script in the template itself, rather than a separate main.js file.
So, at the bottom of your template.py file, you could have something like:
<script type="text/javascript>
var myImg = document.querySelector('img');
var myImgSrc = myImg.getAttribute('src');
var Foo = "{% static 'basic/myImage.jpg' %}";
if (myImgSrc === Foo) { // this should be true
// do something
}
</script>
Also, if main.js is included AFTER this script tag, it should have access to the values of myImgSrc and Foo.
Related
I have an application that takes user input and creates a 3D model from that input in a python script. I now want to visualize this 3D object using three.js.
My problem is that I cannot seem to get the data from the backend to the three.js GLTFLoader in the correct format. The glb data is generated with trimesh. I am certain the 3D model is created correctly because I can output it to a file and open it in Blender.
The loading of static resources in the glb format through three.js also works. But since the content is dynamically created, I do not want to save it on the server-side unless the user decides to keep it.
My current approach is to try and include the 3D model in the content of a template view. The three.js documentation says, glb data can be parsed from a js BufferArray. But it seems the data gets read as a binary string in js: "b'......'"
The views.py:
class PreviewView(TemplateView):
template_name = 'editor/preview.html'
context_object_name = 'preview_generated'
def get_preview(self, request):
from editor.tools.gltf import GLTFConverter
raw_lines = json.loads(request.POST.get('vertex_sets'))
if type(raw_lines[0]) is list:
lines = [np.pad(np.array(line).reshape((-1,2)),[(0,0),(0,1)], mode='constant') for line in raw_lines]
else:
lines = [np.pad(np.array(raw_lines).reshape((-1,2)),[(0,0),(0,1)], mode='constant')]
preview = get_preview(lines)
request.session["preview"] = preview
converter = GLTFConverter(preview.mesh)
scene = converter.get_scene("preview")
return scene
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
def post(self, request, *args, **kwargs):
context = self.get_context_data()
preview = self.get_preview(request)
context['preview'] = preview
return self.render_to_response(context)
The preview.html:
<script src="{% static 'editor/js/three.js' %}"></script>
<script src="{% static 'editor/js/OrbitControls.js' %}"></script>
<script src="{% static 'editor/js/OBJLoader.js' %}"></script>
<script src="{% static 'editor/js/OBJExporter.js' %}"></script>
<script src="{% static 'editor/js/ColladaLoader.js' %}"></script>
<script src="{% static 'editor/js/GLTFLoader.js' %}"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script>
<!-- load the static resources for the editor main.js -->
{% with mannequin_path="editor/models/xyz.gltf" %}
<script>
var mannequin_path = "{{ mannequin_path }}";
var mannequin_url="{% static mannequin_path %}";
var material_url="{% static 'editor/textures/abstract-art-attractive-1122400.jpg' %}";
var csrf = "{{ csrf_token }}"
</script>
{% endwith %}
<script src="{% static 'editor/js/main.js' %}"></script>
{% if preview %}
<script>
var preview = "{{ preview|safe }}";
let loader = new THREE.GLTFLoader();
loader.parse( preview, '', function ( gltf ) {
const model = gltf.scene;
model.traverse((o) => {
if (o.isMesh) {
o.material = generic_material;
}
});
garment = model;
scene.add( model );
},
function( gltf ) {
console.log("no");
}
);
</script>
{% endif %}
I get as an error message in the browser:
"Uncaught SyntaxError: Unexpected identifier (at (index):66:82)"
The line in question reads:
var preview =
"b'glTF\x02\x00\x00\x00\x18\xc1\x00\x00\x0c\x03\x00\x00JSON{"scene":0,"scenes":[{"nodes":[0]}],"asset":{"version":"2.0","generator":"https://github.com/mikedh/trimesh"},"accessors":[{"componentType":5125,"type":"SCALAR","bufferView":0,"count":8664,"max":[1163],"min":[0]},{"componentType":5126,"type":"VEC3","byteOffset":0,"bufferView":1,"count":1164,"max":[0.17265082895755768,1.5097070932388306,0.12908484041690826],"min":[-0.3401854634284973,1.0074307918548584,-0.24667978286743164]}],"meshes":[{"name":"geometry_0","extras":{"processed":true},"primitives":[{"attributes":{"POSITION":1},"indices":0,"mode":4}]}],"nodes":[{"name":"preview","children":[1]},{"name":"geometry_0","mesh":0}],"buffers":[{"byteLength":48624}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":34656},{"buffer":0,"byteOffset":34656,"byteLength":13968}]}
\xf0\xbd\x00\x00BIN\x00\x00\x00\x00\x00\x14\x00\x00\x00\x15\x00\ [...
this part removed ...] e\xce\x12\xa3?\xb6M\x85\xbd'";
I've tried so far:
to convert to json (python error: cannot convert object to json)
to decode the binary string in python (python error: cannot decode due to some character not conforming to utf-8)
to set the content_type of the entire view to "model/gltf-binary" (it generated a file that the browser downloaded)
Has anyone done this before? Can I specify the content_type of just one context variable intead of the entire view? Or is there another way to send dynamic resources to the user without saving them to a database and serving the file through an url?
I am trying to dynamically insert img elements to the website I am building which uses Django for the back-end. The images change often so I pass the src from Python to Javascript like this:
views.py
path='{% static "../static/assets/'+image_name+'" %}'
response = render(request, 'main.html',{'image_path':path})
return response
Then I declare a global variable in the template so I can use this in the .js files.
main.html
var imagePath = {{image_path|safe}}
Then I use Javascript to pass this as src to new img elements. However, when I do it, Django cannot find images. When I put the string as src to a img element manually, it works.
Does anyone know how to solve this?
You need to use this:
from django.templatetags.static import static
path = static(f'assets/{image_name}')
response = render(request, 'main.html',{'image_path':path})
return response
I want to send a variable value to python from flask html/js through url_for().
Python Code :
#app.route('/video_feed/<device>')
def video_feed(device):
# return the response generated along with the specific media
# type (mime type)
print(device)
try:
return Response(gen(int(device)),mimetype = "multipart/x-mixed-replace; boundary=frame")
except Exception as e:
return Response(gen(device),mimetype = "multipart/x-mixed-replace; boundary=frame")
Desired in flask html file:
data.value = 0;
image.src = "{{ url_for('video_feed', device=data.value)}}";
But it does not work, I get the error:
jinja2.exceptions.UndefinedError: 'data' is undefined
This does work, however I can't use the variable data.value in url_for() :
image.src = "{{ url_for('video_feed', device=0)}}";
I have tried several different things like:
image.src = "{{ url_for('video_feed', device=${data.value})}}";
image.src = "{{ url_for('video_feed', device=$data.value)}}";
image.src = "{{ url_for('video_feed', device=%s)}}", data.value;
But nothing seems to work. My javascript is a bit rusty.
Any help would be appreciated!
Cheers!
url_for is expanded on the server side, before the page gets sent to the browser and well before JavaScript runs.
If you know the number (for device/data.value) at page generation time, pass it in to the template via render_template().
If, however, you don't know the value until after the page is rendered, you're going to need to construct the img element from JavaScript.
I'm using Laravel's var ({{ $test }}), assets ({{ asset('upload/img/something.png' }}), route ( {{ route('something.something') }} ) in a js script. This script works correctly if its in a blade file.
I want to has this script inside a js file. I know that I can create a js function and call this in a blade file with arguments, but I have no more arguments. How I can solve my problem?
You can declare your variables in blade file, then include the javascript file to use them.
Example:
In your blade file you declare a url variable:
<script>
var url = "{{ route('something.something') }}";
</script>
Notice that we use var so that the variable will be visible in the scripts below this.
Then you include your script file:
<script src="{{ asset('js/myScript.js' }}"></script>
In that file you can use the url variable.
PS: maybe if you provide more code I will be able to help you more.
I am new to django and eventually I learnt the use of static files in Django and to my relief I was finally able to load the files while hardcoding the file name in the {%static filename.jpg %}. However, when I tried to create a string by replacing the hardcoded filename.jpg with the dynamic file name, I wasn't getting the output.
Not working code snippet:
<script>
image_name = "1.png"
static_start = "{% static '"
static_end = "' %}"
image_src = static_start.concat(image_name, static_end)
window.alert(image_src)
var para = document.createElement("img");
{% load static %}
para.setAttribute("src", image_src)
var element = document.getElementById("div_test");
element.appendChild(para);
</script>
Working Code snippet:
<script>
var para = document.createElement("img");
{% load static %}
para.setAttribute("src", "{%static '1.png'%}")
var element = document.getElementById("div_test");
element.appendChild(para);
</script>
What I am trying to do is that, I have a bunch of image files that I am getting from somewhere through an API and I am storing them in the static folder. After downloading those image, I am trying to load them on my webpage, for that I am using the static file and getting the file name dynamically as I do not know what would the file name of the downloaded file.
The point is that string concatenation isn't working, while directly passing the string is.
Any help would really be appreciated.
P.S.: Apparently in the example shared above I am simply using 1.png which would eventually be replaced by the name of the file I wish to display.
Working code using get_static_prefix (the way I actually wanted)
<script>
image_name = "1.png"
var para = document.createElement("img");
{% load static %}
para.setAttribute("src", "{% get_static_prefix %}" + image_name)
var element = document.getElementById("div_test");
element.appendChild(para);
</script>
I think I understand what you are trying to do here, but I don't think it is possible. Django templates are rendered on the server, and JavaScript is rendered on the client-side. You are trying to create the template tag with JavaScript, but the template tags won't be evaluated on the client-side, they will just be strings.
So after referring to other posts, I realized what I was doing wrong. I believe there was something that wasn't right about string concatenation and the escape characters and therefore Django has an option for get_static_prefix and that is was I was supposed to use instead of that stupid string concatenation. I have edited my question with the correct working response, exactly the way I wanted it to.
References: Stackoverflow question,
Django tutorial