I am new to AngularJS and Djnago Rest Framework. I have created one web api which return list of customers in JSON format. I am getting proper data in RESTClient add-on of mozilla firefox. But i am not able to get data in AngularJS script.
Here i have attached all the codes and error image as below:
views.py (API code)
class CustomerListView(APIView):
renderer_classes = (JSONRenderer, )
def post(self, request, format=None):
content = []
customer_list = Customer_tbl.objects.all()
if customer_list:
for customer in customer_list:
content.append({
'first_name': customer.cus_first_name,
'last_name': customer.cus_last_name,
'email': customer.cus_email,
'contact': customer.cus_contact
})
return Response(content)
test.html
<!DOCTYPE html>
<html ng-app="myTestModule">
<head>
<script src="../scripts/angular.js"></script>
<script src="../scripts/sample_page_test.js"></script>
<link href="../css/style_new.css" rel="stylesheet" />-->
</head>
<body>
<div ng-controller="customerController">
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Contact</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="customer in customers">
<td>{{ customer.first_name }}</td>
<td>{{ customer.last_name }}</td>
<td>{{ customer.email }}</td>
<td>{{ customer.contact }}</td>
</tr>
</tbody>
</table>
</div>
...
...
...
</body>
</html>
sample_page_test.js
var myTestApp = angular.module("myTestModule", [])
myTestApp.controller("customerController", function ($scope, $http) {
var url = "http://192.168.1.102:8000/stl_web_app/api/customer_list/";
$http.post(url).then( function(response) {
$scope.customers = response.data;
});
});
Error Image
getting following error in Firebug console
error.png
Do i need to make any changes in settings.py of django application?
So, Can anyone please help me to solve this issue?
Any help would be greatly appreciated.
Thank you.
First of all, are you actually trying to do a POST request? Because from the looks of it, seems that you are trying to return a list of customers. Please use GET request instead of POST to fetch data.
Secondlly, If you are facing Cross-Origin Resource Sharing issue then check if you have passed correctly CSRF-TOKEN along with the POST request.
views.py
class CustomerListView(APIView):
renderer_classes = (JSONRenderer, )
def get(self, request, format=None):
content = []
customer_list = Customer_tbl.objects.all()
if customer_list:
for customer in customer_list:
content.append({
'first_name': customer.cus_first_name,
'last_name': customer.cus_last_name,
'email': customer.cus_email,
'contact': customer.cus_contact
})
return Response(content)
sample_page_test.js
var myTestApp = angular.module("myTestModule", [])
myTestApp.controller("customerController", function ($scope, $http) {
var url = "http://192.168.1.102:8000/stl_web_app/api/customer_list/";
$http.get(url).then( function(response) {
$scope.customers = response.data;
});
});
Hope this will help you.
Related
This bounty has ended. Answers to this question are eligible for a +50 reputation bounty. Bounty grace period ends in 20 hours.
Joao Daniel is looking for a canonical answer:
Please I need based on my detailed question one which I can test and implement
Currently I have this code that shows me the normal data table but if I have millions of records it becomes very slow, I understand that serverside of datatable can be used but I don't know how I can implement it
list.html
<table class="table table-striped table-hover responsive" style="width:100%" id="buyer">
<thead>
<th>#id</th>
<th>Fecha</th>
<th>Cod Cliente</th>
<th>Cliente</th>
<th>Dirección</th>
<th>Comentario</th>
<th>Tipo Retiro</th>
<th>Total</th>
<th>Guias a Generar</th>
</thead>
<tbody>
{% for item in ResulOrdenes %}
<tr>
<td>{{item.DOCNUM}}</td>
<td>{{item.DOC_DATE|date:"Y-m-d"}}</td>
<td>{{ item.CARDCODE }}</td>
<td>{{ item.CARDNAME }}</td>
<td>{{ item.ADDRESS }}</td>
<td>{{ item.COMMENTS }}</td>
<td>{{ item.URETIRO }}</td>
<td>{{ item.DOCTOTAL }}</td>
<td>{{ item.NGUIAS }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block content_wrapper %}
<p></p>
{% endblock content_wrapper %}
{% block js_page %}
<script>
$(document).ready(function() {
$('.table').DataTable({
dom: 'Bfrtip',
});
</script>
{% endblock %}
view.py
def Listado_guia(request):
template_name='app_listguia/lista.html'
conn = dbapi.connect(..)
cursorSol2 = conn.cursor()
sql_command = 'select a."DocNum" as "DOCNUM", a."DocDate" as "DOC_DATE", a."CardCode" as "CARDCODE", a."CardName" as "CARDNAME", a."DocTotal" as "DOCTOTAL", CEILING(a."DocTotal"/20000) as "NGUIAS", a."DocStatus" as "DOCSTATUS", a."Address" as "ADDRESS", a."Address2" as "ADDRESS2", a."Comments" as "COMMENTS", a."U_Retiro_mercaderia" as "URETIRO" '
sql_command = sql_command + 'from "'+ connections.databases[ConfigBaseHana]["NAME"] +'"."ODLN" as a '
cursorSol2.execute(sql_command)
RES_ORDENES = cursorSol2.fetchall()
cursorSol2.close()
conn.close()
dnow = today.strftime("%Y-%m-%d")
contexto = { "ResulOrdenes":RES_ORDENES, "dnow":dnow }
return render(request,template_name,contexto)
urls.py
from django.urls import path
from django.contrib.auth import views as auth_views
from app_guia.views import *
urlpatterns = [
path('guiaList',Listado_guia,name='urlListGuia_list'),
]
Can you please give me some light on how to proceed? Thanks
The approach you are using is not suitable for millions of records. First of all, if this is your complete sql, you should stick with normal Django QuerySets and switch your view to use a (generic) class-based view. This gives you a proper paginator, which will reduce the load on the database, django and the resulting html significantly.
If you do not want to have pagination, but rather a continuous list, you need a javascript component to virtually render your table. This way, only a few hundred DOM nodes are present in the clients javascript, and will be populated from server, on the fly, while scrolling. The term to search for is "virtualized table", an examplatory candidate would be react-window.
On a sidenote: if the code shown is your "real" production code (and not a boiled-down demo version for this post), I highly recommend working through a django tutorial, e.g. here or here, and sticking to the default django way as documented in the djangoproject as much as possible. You will save yourself hours of programming and huge problems with future enhancements.
To improve the performance of your data table, you can use the server-side processing mode of the DataTables library.
Add the serverSide option to your DataTable initialization code and
set it to true:
$(document).ready(function() {
$('.table').DataTable({
serverSide: true,
processing: true,
ajax: '/guiaList',
dom: 'Bfrtip',
});
});
In your view function, you need to handle the AJAX request and return
the data in the expected format. You can use the JsonResponse class
from Django to return the data in JSON format
from django.http import JsonResponse
from django.core.paginator import Paginator
def Listado_guia(request):
draw = int(request.GET.get('draw', 1))
start = int(request.GET.get('start', 0))
length = int(request.GET.get('length', 10))
conn = dbapi.connect(...)
cursorSol2 = conn.cursor()
sql_command = 'SELECT ...'
cursorSol2.execute(sql_command)
total_items = cursorSol2.rowcount
results = cursorSol2.fetchall()
cursorSol2.close()
conn.close()
paginator = Paginator(results, length)
page_results = paginator.get_page(int(start/length)+1)
data = []
for item in page_results:
data.append({
'DOCNUM': item[0],
'DOC_DATE': item[1].strftime("%Y-%m-%d"),
'CARDCODE': item[2],
'CARDNAME': item[3],
'DOCTOTAL': item[4],
'NGUIAS': item[5],
'DOCSTATUS': item[6],
'ADDRESS': item[7],
'ADDRESS2': item[8],
'COMMENTS': item[9],
'URETIRO': item[10]
})
response = {
'draw': draw,
'recordsTotal': total_items,
'recordsFiltered': total_items,
'data': data
}
return JsonResponse(response)
The start, length, and draw parameters are sent automatically by DataTables to the server when requesting data. The start parameter indicates the start index of the current page, the length parameter indicates the number of rows to display on the current page, and the draw parameter is used to ensure that the response matches the current state of the table.
The JsonResponse returns the data in the format expected by DataTables, which includes the draw parameter, the total number of records (recordsTotal), the number of filtered records (recordsFiltered), and the data array.
Using flask, I want to select a user from a table and then redirect the page with the id of the selected user. My code looks something like this:
HTML:
<form action="" method="POST">
<table>
<tr>
<th>Id</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
{% for user in users %}
<tr type="submit" name="action" value="{{user.user_id}}">
<td>{{user.user_id}}</td>
<td>{{user.first_name}}</td>
<td>{{user.last_name}}</td>
</tr>
{% endfor %}
</table>
</form>
Python:
def userSelect():
if request.method == 'POST':
return redirect(url_for('user', user=request.form['action']))
return render_template('userSelect.html', users=user.query.all())
I have also tried using JQuery to make the post, but I am unsure how to then use the id in the page that I redirected to, and I can't redirect from flask after having made a post from JQuery:
$("table tr").on("click",function()
{
var selected = $("td:first", this).text();
$.post("/user", {user_id: selected}, function(){
window.location.href = "/user";
});
});
EDIT:
Let's just say I want to display that id on the page I redirect to (something like this):
#app.route("/user")
def user(user):
return user
With your Jquery's code, it will make an ajax to server
$.post("/user", {user_id: selected}, function(){
window.location.href = "/user";
});
so, Flask can not redirect, if you edit code look like:
$.post("/user", {user_id: selected}, function(data){
console.log(data);
});
you will see Flask had returned HTML of the redirected page.
Finally, I think this is help you:
Flask:
#app.route('/user/<user_id>')
def userHasSelected(user_id):
....
// I don't know why do you need this return redirect
return redirect(url_for('user', user=request.form['action']))
JS:
$("table tr").on("click",function()
{
var selected = $("td:first", this).text();
// {{url_for('user', user_id=selected)}} it will be rending from server
window.location.href = {{url_for('user', user_id=selected)}}
// or
window.location.href = `/user?user_id=${selected}`;
});
I'm trying to create an content editable HTML table that'll update the db.sqlite3 database on keypress. The table can't have an input field in it because I also require it to be able to be filter and search using data-tables. so far I manage to retrieve the input on enter keypress but i don't know how to POST it straight to database (Presumably using AJAX) instead of JSON. Can anyone provide me with complete syntax sample as well, I'm very new to Django
Here's my code :
Model.py
class MyModel(models.Model):
a = models.CharField(max_length=10)
b = models.CharField(max_length=10)
def __str__(self):
return self.a
form.py
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['a', 'b']
view.py
def display_table(request):
context = {
"table_list": MyModel.objects.all(),
"title": "Table_List"
}
return render(request, 'tables/display.html', context)
display.html
<form action="" method="post" id="test_post">{% csrf_token %}
<div id="debug" contenteditable data-name="custom-text">Some text you can edit.</div>
<table id="myTable" class="display">
<thead>
<tr>
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
{% for data in table_list %}
<tr >
<td contenteditable="true" data-name="a_name" id="{{data.id}}">{{data.a}}</td>{% csrf_token %}
<td contenteditable="true" data-name="b_name" >{{data.b}}</td>{% csrf_token %}
</tr>
{% endfor %}
</tbody>
</table>
</form>
<script>
document.addEventListener('keydown', function (event) {
var esc = event.which == 27,
nl = event.which == 13,
el = event.target,
data = {};
if (esc) {
// restore state
document.execCommand('undo');
el.blur();
} else if (nl) {
// save
data[el.getAttribute('data-name')] = el.innerHTML;
// we could send an ajax request to update the field
$.ajax({
data: data,
type: "POST"
});
log(JSON.stringify(data));
el.blur();
event.preventDefault();
}
}, true);
function log(s) {
document.getElementById('debug').innerHTML = 'value changed to: ' + s;
console.log(s);
}
</script>
<script>
$(document).ready(function(){
$('#myTable').DataTable();
});
</script>
Thank you very much for everyone's help.
Yes you're right about using AJAX. A few things you will need to modify:
1. Your HTML/JS
$.ajax({
data: data,
type: "POST",
// include URL
url: 'url/to/post/to',
// include response handler here
success: function(response) {
// do whatever you want with response
// you can just console.log(response.data) first
},
error: function(response) {
// error handler to failed AJAX requests
}
});
2. Views
You'll need to change your view to return a JsonResponse instead of using render which creates an HTML response. Note that the JsonResponse will be the exact response received in the AJAX handler above.
Hope this helps.
My Django project is returning a TypeError: 'module' object is not iterable.
I know this type of question is already being asked in community, but none of previous questions could fixed my issue.
perhaps I don't understand something basic, as I'm a novice who freshly learning Python and Django. does anyone can help me to solve this issue?
I created a model as following.
from django.db import models
# Create your models here.
class Article(models.Model):
content = models.CharField(max_length=200)
written_date = models.DateTimeField('date written')
def __unicode__(self):
return self.content
Following is view.py
# Create your views here.
from blog.models import Article # Article data models
from django.shortcuts import render # shortcuts to call template
from django.http import HttpResponseRedirect # Redirection Module
from django.template import context
from django.utils import timezone # time Module
# blog.views.index
# retrieve all content and display in reverse of order of written_date
# call the template after sorting.
def index(request):
all_articles = Article.objects.all().order_by('-written_date')
return render({'all_articles' : all_articles, 'message' : 'Write something!'},
'blog/index.html', context)
# blog.views.submit
# Receive POST request submitted from user FORM, save the request
# redirect user to index.html
def submit(request):
try:
cont = request.POST['content']
except (KeyError):
return render({'all_articles' : all_articles, 'message' : 'Failed to read content'},
'blog/index.html', context)
else:
article = Article(content=cont, written_date=timezone.now())
article.save()
return HttpResponseRedirect('/blog')
# blog.views.remove
# delete content which has primary key matched to article_id
# redirect user after deleting content
def remove(request, article_id):
article = Article.objects.get(pk=article_id)
article.delete()
return HttpResponseRedirect('/blog')
Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>One Line Blog</title>
<link rel="stylesheet" href="{{ STATIC_URL }}styles/blog.css" type="text/css">
</head>
<body>
<div id="header">
<h2>One Line Blog</h2>
</div>
<div id="writer">
<div>
{% if message %}<p><strong>{{ message }}</strong></p>{% endif %}
</div>
<form action="/blog/submit" method="post">
{% csrf_token %}
<input type="text" max-length=200 style="width:500px;" name="content">
<input type="submit" value="Submit">
</form>
</div>
<div>
{% if all_articles %}
<table>
<tr>
<th>No. </th>
<th width="300px">Content</th>
<th>Date</th>
<th>Delete</th>
</tr>
{ % for article in all_articles %}
<tr>
<td>{{ article.id }}</td>
<td>{{ article.content }}</td>
<td>{{ article.written_date }}</td>
<td align="center">[x]</td>
</tr>
{ % endfor %}
</table>
{% else %}
<p>No articles available</p>
{% endif %}
</div>
</body>
</html>
The signature of render is:
render(request, template_name, context=None, content_type=None, status=None, using=None)
You, however, call it in your index view:
return render({'all_articles' : all_articles, 'message' : 'Write something!'},
'blog/index.html', context)
where you pass a dict as request (bad enough) and, which causes the error, as third positional argument (which should be a dict) you pass a variable by the name of context which is a module that you have imported via
from django.template import context
Change it to
return render(request, 'blog/index.html',
context={'all_articles': all_articles, 'message': 'Write something!'})
You made the same mistake in your submit view.
I am trying to display a list of users that get updated using AJAX at the same time a new user is added using admin page .
Django 1.9 , Python 3.5 , I am working with a windows machine
My index.html
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{% for User in users %}
<tr>
<td>{{ User.username }}</td>
<td>{{ User.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
My views.py
def index(request):
context = RequestContext(request)
users=User.objects.all()
return render_to_response('index.html',{'users':users},context)
How to implement AJAX ? Please help me how to use ajax with Django and fulfill this simple task.
Welcome to stackoverflow!
If you simply wants to call Ajax using Django then You should try this:
views.py
def index(request):
return render(request, 'index.html', locals())
def ajax_view(request):
result = dict()
data_list = []
result['status'] = "success"
for u in User.objects.all():
list_of_user = {'email': u.email, 'first_name': u.first_name}
data_list.append(list_of_user)
result['data'] = data_list
return HttpResponse(json.dumps(result), content_type='application/x-json')
index.html
<script src="/path/to/js/my_ajax.js"></script>
<table class="myTable">
<thead>
</thead>
<tbody>
</tbody>
</table>
my_ajax.js
$( document ).ready(function() {
$.ajax({
type: 'GET',
url: '/ajax/',
success: function (result) {
if (result.status == "success") {
if (result['data']) {
jQuery.each(result['data'], function (i, val) {
$('.myTable').append(
'<tr><td id="first_name">'+val['first_name']+'</td>' +
'<td id="email">'+val['email']+'</td></tr>');
});
}
}
}
})
});
urls.py
url(r'^ajax/$', ajax_view, name='temp'), # Function calls ajax
url(r'^index/$', index, name='index'), # main function redirect to index.html
This will call your ajax and get User's data.