How to pass data from django to js from html template - javascript

I have following files as mentioned below and I want to know how can I pass the django username to js in the index.html file
view.py file
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from .models import Message
import json
def index(request):
return render(request, 'chat/index.html')
#login_required
def room(request, room_name):
messages = Message.objects.filter(room=room_name)[0:25]
return render(request, 'chat/room.html', {'room_name': room_name,
'username': json.dumps(request.user.username),'messages': messages})
models.py file
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Message(models.Model):
username = models.CharField(max_length=50)
room = models.CharField(max_length=255)
content = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('date_added',)
def __str__(self):
return self.username
script in index.html
<script>
document.querySelector('#room-name-input').focus();
document.querySelector('#room-name-submit').onclick = function(e) {
var roomName = document.querySelector('#room-name-input').value;
var userName = JSON.parse( {{ username|safe }} );
window.location.replace(roomName + '/?username=' + userName);
};
</script>

var userName = JSON.parse( `{{ username|safe }}` ); // add quotes

Try using quotation to wrap the Django variable in the js. For example:
var userName = JSON.parse("{{ username|safe }}");

I solved this by using from django.utils.safestring import mark_safe with the json.dumps in the views.py file
from django.shortcuts import render
from django.utils.safestring import mark_safe
from django.contrib.auth.decorators import login_required
from django.contrib.auth import get_user_model
from .models import Message
import json
User = get_user_model()
def index(request):
username = mark_safe(json.dumps(request.user.get_username()))
return render(request, 'chat/index.html',{'username':username})
#login_required
def room(request, room_name):
messages = Message.objects.filter(room=room_name)[0:25]
return render(request, 'chat/room.html', {'room_name': room_name,
'username': mark_safe(json.dumps(request.user.get_username())),'messages': messages})
index.html
<script>
document.querySelector('#room-name-input').focus();
document.querySelector('#room-name-submit').onclick = function(e) {
var roomName = document.querySelector('#room-name-input').value;
var userName = {{ username }}
console.log(userName);
window.location.replace(roomName+ '/?username=' + userName);
};
</script>

Related

ReactJS, Django , GraphQL - Uploading file

I am trying to upload a file in frontend and send the data to Django backend using graphql.
function Integrations() {
const [importTranscations] = useMutation(IMPORT_TRANSACTIONS);
function onChange({
target: {
validity,
files: [file],
},
}) {
if (validity.valid) {
importTranscations({ variables: { file } });
}
}
return (
<div
style={{
padding: "20px",
}}
>
<input type="file" required onChange={onChange} />
</div>
);
}
export default Integrations;
When I inspect the network tab and observe the graphql api call, I can observe that an empty object is being sent as 'file':
I have also added logs in the Django backend where I am using graphene-file-upload module. I am getting file as an empty Dictionary.
URLs:
from django.urls import path
from django.contrib import admin
from django.views.decorators.csrf import csrf_exempt
from graphene_file_upload.django import FileUploadGraphQLView
urlpatterns = [
path("admin/", admin.site.urls),
path("graphql/", csrf_exempt(FileUploadGraphQLView.as_view())),
]
Mutations:
import graphene
from graphene_file_upload.scalars import Upload
class ImportTransactionsMutation(graphene.Mutation):
class Arguments:
file = Upload(required=True)
task_id = graphene.String()
def mutate(self, info, file):
print("## DEBUGGING ## -> file", file)
task_id = "sample"
return ImportTransactionsMutation(task_id=task_id)
This is the output that I am seeing in the console:
## DEBUGGING ## -> file {}
Here is a link to codesandbox. You can open the network tab and check the graphql API.

How to update a Django html element with javascript and Ajax

I am trying to update an html element on web page with javascript. When the home page loads, it works perfectly, but when I click on New Product link just the context string is displayed on the home page
html
<!-- product/home.html -->
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
<title>Test context</title>
</head>
<body>
<h1>Test context</h1>
<div class="container">
{% block content %}
Product: <span id="product-code"></span>
<p>New Product<p>
{% endblock content %}
<script type="text/javascript" src="{% static 'js/product.js' %}"></script>
</div>
</body>
</html>
urls.py
# cardplay/urls.py
from django.urls import path
from .views import HomePageView, NewProduct
urlpatterns = [
path('', HomePageView.as_view()),
path('new-product', NewProduct.as_view(), name= 'new-product'),
]
views.py
# /product/views.py
import random
from django.views.generic import View
from django.shortcuts import render
from django.http import JsonResponse
class HomePageView(View):
template = 'product/home.html'
def get(self, request):
context = {}
return render(request, self.template, context)
class NewProduct(View):
def get(self, request):
code = random.choice(['A123','M456', 'X789'])
context = {
'code': code,
}
return JsonResponse(context)
product.js
$(document).ready(function () {
getNewProduct();
});
function getNewProduct() {
$.ajax(
{
type: "GET",
url: 'new-product',
cache: false,
success: function (context) {
displayNewProduct(context);
}
}
);
}
function displayNewProduct(context) {
var productCode = document.getElementById('product-code');
productCode.innerText = context.code;
}
What am I doing wrong?
I was not calling the function as #Swati pointed out
product.js
$(document).ready(function () {
product_link = document.getElementById('product_link')
product_link.onclick = function(){getNewProduct()};
getNewProduct();
});
...
html
...
<p><button id="product_link">New Product</button></p>
...

how to retrieve first app model data in second app in Django

how to retrieve first app model data in second app in Django.
I create a model scheme_details_model in trible app and I have to display field scheme_title to the home1.html of the theme.
# this is model in trible app
class scheme_details_model(models.Model):
scheme_id = models.CharField(max_length=200, blank=False, null=True)
scheme_title = models.CharField(max_length=200, default='')
publish_on = models.CharField(max_length=200, default='')
detail_description = models.CharField(max_length=200, blank=False,
null=True)
validity_upto = models.CharField(max_length=50, null=True, blank=True)
pdf_doc_type = models.FileField(upload_to="driver_file/",
validators=[validate_file_extension],
null=True)
source_url = models.CharField(max_length=100, null=True, blank=True)
created_date = models.DateTimeField(default=datetime.now, blank=True)
modified_date = models.DateTimeField(auto_now=True)
class Meta:
db_table = "scheme_details_table"
# view function in theme app
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from DigitalMine.tribal.models import scheme_details_model
#login_required
def home(request):
book = scheme_details_model.objects.all()
data = {}
data['object_list'] = book
print(data)
return render(request, "home1.html")
display "scheme_title" field as a link to redirect to another page
I think you forgot to pass the data to template file. Change this code:
return render(request, "home1.html")
to:
return render(request, "home1.html", data)
And then you can access the variable into your html file like this:
{% for scheme in object_list %}
{{ scheme.scheme_title }}
{% endfor %}

NoReverseMatch from url tag inside include tag

I am trying to render a link inside an include html template with the url tag.
I have done this before and usually it works, but for some reason this time I can't make it.
I get a NoReverseMatch Error and suspect its because Django tries to load the url tag first but my object isn't ready, so the pk is empty. I believe that because it takes a moment until the dynamic data loads, while the static is already loaded.
The url works if I set pk to a fixed number, but I would like it to change dynamically.
Error:
Reverse for 'transaction' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['en/budget/account\\/(?P<pk>[0-9]+)\\/$']
Relevant urls:
from django.urls import path
from django.contrib import admin
from django.contrib.auth import views as auth_views
from . import views
app_name='budgetapp'
urlpatterns = [
path('', views.index, name='index'),
path('account/<int:pk>/', views.transaction, name='transaction'),
path('account/', views.account, name='account'),
]
Relevant views:
from django.shortcuts import get_object_or_404, render, redirect
from django.contrib.auth.models import Group
from django.contrib.auth.decorators import login_required, user_passes_test
from .models import *
from .forms import *
def index(request):
context = {}
context['accounts'] = Account.objects.filter(author=request.user)
return render(request, 'budgetapp/index.html', context)
def account(request):
context = {}
context['account'] = get_object_or_404(Account, pk = request.POST['accountPk'])
return render(request, 'budgetapp/account.html', context)
def transaction(request, pk):
context = {}
context['account'] = get_object_or_404(Account, pk = pk)
return render(request, 'budgetapp/addTransaction.html', context)
index.html:
{% csrf_token %}
<h1>Personal Budget</h1>
<br />
<p>
<label for="accountSelector">Account:</label>
<select required = "" id="accountSelector">
{% for account in accounts %}
<option value="{{account.pk}}">{{account}}</option>
{% endfor %}
</select>
</p>
<hr />
{% include 'budgetapp/account.html' %}
<script>
$(document).ready(function () {
reload();
});
$("#accountSelector").change(function () {
reload();
});
function reload() {
var dictionary = {}
dictionary['csrfmiddlewaretoken'] = $('input[name="csrfmiddlewaretoken"]').val();
dictionary['accountPk'] = $('#accountSelector').val();
$('#accountDiv').load("account/", dictionary);
console.log('Changed account');
}
</script>
account.html:
<div id="accountDiv">
<p>
Name: {{account.name}} Account balance: {{account.balance}} Add a transaction
</p>
</div>
If I change {% url 'budgetapp:transaction' pk=account.pk %} to /budget/account/{{account.pk}} it works, but that feels wrong.
I tried to provide all necessary code, but please let me know if it is to much or something is missing.
If you want to use {% url 'budgetapp:transaction' pk=account.pk %} then account must be in the template context. This has nothing to do with your browser dynamically loading data. The entire template is rendered by the server before the response is sent to the browser.
Using /budget/account/{{account.pk}} won't give an error, but if you look at the rendered HTML you'll see /budget/account/ since {{ account.pk }} will evaluate as ''.

How to change the contents of a block dynamically on django?

SEE FIXED CODE BELOW
I'm working on my first web page project using django 1.8. My web page has a section that consists of a product menu and a column displaying a different view based on selected menu item.
At first I tried an approach where each of the menu buttons have a onclick js function assigned that changes the contents of the block. I was thinking that I would then write the html code of each product into separate file where it would be read by the js function. I got it partially working but it feels kinda sketchy.
My second approach was based on using django templates but I run into some errors as a beginner I couldn't quite figure out what exactly is the problem. I would highly appreciate if someone could pinpoint what I'm doing wrong or tell me what's the right approach for changing the contents dynamically.
The errors I'm getting currently:
http://127.0.0.1:8000/productmonitor/
NoReverseMatch at /productmonitor/
Reverse for 'product' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'productmonitor/(?P<product_name>[a-z]+)/$']
http://127.0.0.1:8000/productmonitor/
NoReverseMatch at /productmonitor/dualpol/
Reverse for 'product' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'productmonitor/(?P<product_name>[a-z]+)/$']
urls.py
# -*- coding: utf-8 -*-
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<product_name>[A-Za-z0-9\-\_]+)/$', views.product, name='product'),
url(r'^information/$', views.information, name='information'),
url(r'^casedatabase/$', views.casedatabase, name='casedatabase'),
url(r'^contact/$', views.contact, name='contact'),
]
views.py
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from django.views import generic
# Create your views here.
from .models import Product
def index(request, product_name='default'):
#template = 'productmonitor/index.html'
if product_name == 'dualpol':
template = 'productmonitor/base_productmonitor_dualpol.html'
if product_name == 'rhi':
template = 'productmonitor/base_productmonitor_rhi.html'
template = 'productmonitor/base_productmonitor.html'
test_context = {
'products' : Product.objects.all(),
}
return render(request, template, test_context)
def product(request, product_name='dualpol'):
if product_name == 'dualpol':
template = 'productmonitor/base_productmonitor_dualpol.html'
if product_name == 'rhi':
template = 'productmonitor/base_productmonitor_rhi.html'
test_context = {
'products' : Product.objects.all(),
}
return render(request, template, test_context)
base_productmonitor.html
{% extends "productmonitor/base.html" %}
{% block content %}
<div class="productSelectMenu">
<ul>
<p>Test</p>
{% for product in products %}
<li><a href="{% url 'productmonitor:product' 'dualpol' %}">{{ product.name }}<a/></li>
{% endfor %}
</ul>
</div>
{% block productcontent %}
<div id="productView" class="productView">
<p>Default productView content</p>
</div>
{% endblock %}
{% endblock %}
base_productmonitor_dualpol.html
{% extends "productmonitor/base_productmonitor.html" %}
{% block productcontent %}
<p>
dualpol
</p>
{% endblock %}
EDIT: FIXED VERSION
urls.py
# -*- coding: utf-8 -*-
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^product/(?P<product_name>[a-z]+)/$', views.product, name='product'),
url(r'^information/$', views.information, name='information'),
url(r'^casedatabase/$', views.casedatabase, name='casedatabase'),
url(r'^contact/$', views.contact, name='contact'),
]
views.py
enter code here
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render, redirect
from django.views import generic
# Create your views here.
from .models import Product
def index(request, product_name=''):
return redirect('productmonitor:product', product_name='dualpol')
def product(request, product_name):
if product_name == 'dualpol':
template = 'productmonitor/base_productmonitor_dualpol.html'
if product_name == 'rhi':
template = 'productmonitor/base_productmonitor_rhi.html'
test_context = {
'products' : Product.objects.all(),
}
return render(request, template, test_context)
def information(request):
template = 'productmonitor/base_information.html'
context = {}
return render(request, template, context)
def casedatabase(request):
template = 'productmonitor/base_case-database.html'
context = {}
return render(request, template, context)
def contact(request):
template = 'productmonitor/base_contact.html'
context = {}
return render(request, template, context)
base_productmonitor.html
{% extends "productmonitor/base.html" %}
{% block content %}
<div class="productSelectMenu">
<ul>
<li><a href="{% url 'productmonitor:product' 'dualpol' %}">Dual pol<a/></li>
<li><a href="{% url 'productmonitor:product' 'rhi' %}">Rhi<a/></li>
</ul>
</div>
{% block productcontent %}
<div id="productView" class="productView">
<p>Default productView content</p>
</div>
{% endblock %}
{% endblock %}
base_productmonitor_dualpol.html
{% extends "productmonitor/base_productmonitor.html" %}
{% block productcontent %}
<div id="productView" class="productView">
<p>
dualpol
</p>
</div>
{% endblock %}
I think what the error is saying that the render in your product function is not getting the right <product_name> to use. It's showing that the arguments that it has (the <product_name> that it is trying) are none. So what you have to do in your product function is to try and make sure that you are really getting a <product_name>.

Categories