How to pass 2 variables using json dumps to an ajax function? - ajax

I want to pass two variable: scenario_name and scenario_id from my view to my ajax function in the html code.
So basically in the database, each Organization can have multiple scenarios. The organization and scenario models have 2 fields each: an id field and a name field.
And my other doubt is, once I pass it to ajax, how do I access the variables passed?
my views.py
from django.shortcuts import render, redirect
from Organization.models import Organization
from django.http import HttpResponse
from Scenario.models import Scenario
import json
from django.core import serializers
def alertindex(request):
return render(request, 'alertindex.html', {
'Organization': Organization.objects.all(),
})
def get_scenario(request):
org_id = request.GET.get('org_id')
organization = Organization.objects.get(pk=int(org_id))
scenario = organization.scenario_set.all()
scenarios = serializers.serialize("json", scenario)
return scenarios
urls.py
from . import views
from django.conf.urls import url
urlpatterns = [
# Add alert url
url(r'^$', views.alertindex, name='alertindex'),
# Bind data in scenario drop down
url(r'^/Scenario$', views.get_scenario, name='Get_Scenario'),
]
my ajax function
var orgID = $(this).val();
var scenarios = '{{ scenarios }}'
$.ajax({
type: "GET",
url: "{% url 'Get_Scenario' %}",
data: { org_id: orgID},
success: function () {
var udata = "";
for (var i = 0; i < scenarios.length; i++) {
udata = udata + "<option value='"+ scenarios[i].scenario_id + "'>" + scenarios[i].scenario_name + "</option>"
$("#txtScenario").append(udata);
}
},
});
The url Get_Scenario links me to my view having the function get_scenario.
The error that I am facing is " str' object has no attribute 'get' "
Traceback:
File "/Users/anirudhchakravarthy/anaconda3/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/Users/anirudhchakravarthy/anaconda3/lib/python3.6/site-packages/django/utils/deprecation.py", line 97, in call
response = self.process_response(request, response)
File "/Users/anirudhchakravarthy/anaconda3/lib/python3.6/site-packages/django/middleware/clickjacking.py", line 26, in process_response
if response.get('X-Frame-Options') is not None:
AttributeError: 'str' object has no attribute 'get'
Any help will be greatly appreciated.

You can use JsonResponse. Here's sample code.
(It's better to check try/exception and send 404 when not found object)
from django.http import JsonResponse
def get_scenario(request):
org_id = request.GET.get('org_id')
# you can do your own validation
try:
organization = Organization.objects.get(pk=int(org_id))
scenario = organization.scenario_set.all()
scenarios = serializers.serialize("json", scenario)
except ObjectDoesNotExist:
data = {
'result': 'fail',
}
return JsonResponse(status=404, data)
data = {
"scenarios": scenarios,
# add more data you want
}
return JsonResponse(data)
For more information about JsonResponse, just check here

Related

Next.js seems to cache files as in a route of _next/data/[path].json preventing getStaticProps from running in server side render

The issue appears to happen when I post the link on platforms like Discord and Slack, where then to produce a URL preview they send a request to the link. The link which in this case follows this structure (normal format) www.domain.com/ctg/[...ids].
Within [...ids] I either pass one of two ids for the same object, the object has the following structure:
type Catalogue {
id: ID!
edit_id: String!
user_id: String!
title: String
...
}
The first id I could pass into [...ids] would be Catalogue.id
The second id I could pass into [...ids] would be Catalogue.edit_id
Whenever either of those inputs for [...ids] is passed as part of a request the following getStaticProps is ran:
export const getStaticProps: GetStaticProps = async ({ params }) => {
const { ids } = params;
let catalogue: CatalogueType | null = await fetchFullCatalogue(ids[0]);
return {
props: {
catalogue_prop: catalogue,
params,
},
};
};
with fetchFullCatalogue being:
export const fetchFullCatalogue = async (
id: string
): Promise<CatalogueType | null> => {
let catalogue: CatalogueType;
const fetchToUrl =
process.env.NODE_ENV === "development"
? "http://localhost:4000/graphql"
: process.env.BACKEND_URL + "/graphql";
// create a axios fetch request to the http://localhost:4000/graphql
const query = `
<...SOME FRAGMENTS LATER...>
fragment AllCatalogueFields on Catalogue {
id
edit_id
user_id
status
title
description
views
header_image_url
header_color
author
profile_picture_url
event_date
location
created
updated
labels {
...AllLabelFields
}
listings {
...AllListingFields
}
}
query Catalogues($id: ID, $edit_id: String) {
catalogues(id: $id, edit_id: $edit_id) {
...AllCatalogueFields
}
}`;
const config: AxiosRequestConfig = {
method: "post",
url: fetchToUrl,
headers: {
"Content-Type": "application/json",
},
data: JSON.stringify({
query,
variables: { id: id, edit_id: id },
}),
};
let response = await axios(config);
if (response.data.errors) return null;
catalogue = response.data.data.catalogues[0];
console.log("catalogue", catalogue);
return catalogue;
};
The request it is making is to the following API endpoint
Query: {
catalogues: async (
_: null,
args: { id: string; edit_id: string }
): Promise<Catalogue[]> => {
let catalogues: Catalogue[];
// when both id and edit_are passed
if (args.id && args.edit_id) {
catalogues = await getFullCatalogues(args.id, "id", true);
// the following convoluted request is the result of
// me responding to the fact that only the edit_id was working
if (catalogues.length === 0) {
catalogues = await getFullCatalogues(args.edit_id, "edit_id", true);
if (catalogues.length === 0) {
throw new UserInputError("No catalogues found");
}
} else {
catalogues = await getFullCatalogues(
catalogues[0].edit_id,
"edit_id",
true
);
}
console.log("catalogues", catalogues);
} else if (args.id) {
catalogues = await getFullCatalogues(args.id);
} else if (args.edit_id) {
catalogues = await getFullCatalogues(args.edit_id, "edit_id");
} else {
const res = await db.query(fullCatalogueQuery());
catalogues = res.rows;
}
return catalogues;
},
...
},
This results in the following output within the deployed logs:
The logs show the data when the Catalogue is first created which simultaneously navigates me to the URL of "normal format" with Catalogue.id which is interpreted as /_next/data/qOrdpdpcJ0p6rEbV8eEfm/ctg/dab212a0-826f-42fb-ba21-6ebb3c1350de.json. This contains the default data when Catalogue is first generated with Catalogue.title being "Untitled List"
Before sending both requests I changed the Catalogue.title to "asd".
Notice how the request with the Catalogue.edit_id which was sent as the "normal format" was interpreted as /ctg/ee0dc1d7-5458-4232-b208-1cbf529cbf4f?edit=true. This resulted in the correct data being returned with Catalogue.title being "asd".
Yet the following request with the Catalogue.id although being of the same "normal format" never provoked any logs.
(I have tried sending the request without the params ?edit=true and the same happens)
Another important detail is that the (faulty) request with the Catalogue.id produces the (faulty) URL preview much faster than the request with Catalogue.edit_id.
My best theory as to why this is happening is that the data of the URL with Catalogue.id is somehow stored/cached. This would happen as the Catalogue is first created. In turn it would result in the old stored Catalogue.id being returned instead of making the fetch again. Whereas the Catalogue.edit_id makes the fetch again.
Refrences:
Live site: https://www.kuoly.com/
Client: https://github.com/CakeCrusher/kuoly-client
Backend: https://github.com/CakeCrusher/kuoly-backend
Anything helps, I felt like ive tried everything under the sun, thanks in advance!
I learned that For my purposes I had to use getServerSideProps instead of getStaticProps

Play framework show States list from DB based on selected Country Id using AJAX

I am a newbie to Play Framework with Scala. Currently in my project's registration form I have options of Country and States in Drop down. I need to show the States list for the selected Country. Using an AJAX call for this purpose I have used the below code snippet. But it shows
Cannot write an instance of Seq[(String, String)] to HTTP response.
Try to define a Writeable[Seq[(String, String)]]
What I tried
addStudent.scala.html
<div>
Country:
#select(
studentForm("country"),
countryList,
'_default -> "-- Choose Country --",
'onChange->"ajaxCallforStateList(this.value)")
</div>
<script>
function ajaxCallforStateList(countyid) {
ajaxCall(countyid);
var testAjax = jsRoutes.controllers.Students.ajaxCall(countyid);
$.ajax({
url : testAjax.url
});
}
var ajaxSuccess = function(action, data) {
$("body").append("<br/>");
$("body").append(action + " " + data);
};
var ajaxError = function(action, error) {
alert(action + " : " +error);
}
function ajaxCall(countyid) {
var ajaxCallBack = {
success : onSuccess,
error : onError
}
jsRoutes.controllers.Students.ajaxCall(countyid).ajax(ajaxCallBack);
};
var onSuccess = function(data) {
alert(data);
}
var onError = function(error) {
alert(error);
}
</script>
JavascriptRoute.scala
package controllers
import play.api.Routes
import play.api.mvc.Action
import play.api.mvc.Controller
import play.api.mvc.EssentialAction
import play.core.Router.JavascriptReverseRoute
import play.core.Router._
import routes.javascript.Application.index
import routes.javascript.Students.ajaxCall
object JavascriptRoute extends Controller {
/* Application related JavascriptReverse Route will goes here */
val appRoutes: List[JavascriptReverseRoute] = List(index, ajaxCall)
/* All JavascriptReverse Route will combine here */
val javascriptRouters = appRoutes
/**
* This is use to generate JavascriptReverseRoute for all provided actions
*
* #return
*/
def javascriptRoutes: EssentialAction = Action { implicit request =>
import routes.javascript._
Ok(Routes.javascriptRouter("jsRoutes")(javascriptRouters: _*)).as("text/javascript")
}
}
routes
GET /ajax-call/:countryId controllers.Students.ajaxCall(countryId:String)
#Javascript Routes
GET /javascriptRoutes controllers.JavascriptRoute.javascriptRoutes
Students.scala
def ajaxCall(countryId:String) = Action { implicit request =>
Ok(stateList.options(countryId))
}
Student.scala
case class stateList(stateid:Option[Int] = None,
statename: String)
object stateList{
val simple = {
get[Option[Int]]("state.STATE_ID") ~
get[String]("state.STATE") map {
case stateid~statename => stateList(stateid,statename)
}
}
def options(countryId:String): Seq[(String,String)] = DB.withConnection { implicit connection =>
SQL("select * from state WHERE COUNTRY_ID = {countryid}")
.on('countryid->countryId)
. as(stateList.simple *).
foldLeft[Seq[(String, String)]](Nil) { (cs, c) =>
c.stateid.fold(cs) { id => cs :+ (id.toString-> c.statename) }
}
}
}
You're attempting to render a Seq[(String,String)] (from stateList.options(countryId)) as the body of an Action, but you haven't told Play how to serialize it. You could define a Writeable (https://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.http.Writeable) to tell Play how to convert your Seq into something your client will know how to read. Presumably you're looking for a simple string, so either your Writeable wants to be a very simple conversion, or you could even change Ok(stateList.options(countryId)) to be Ok(stateList.options(countryId).mkString("[",",","]")).
According to your existing code and if I understood the question correctly, a quick way to output a JSON would be
OK(JsArray(stateList.options(countryId).map{case (id, name) =>
JsObject(Seq(
"id" -> JsString(x.id),
"name" -> JsString(x.name)
))
}))

Django: TypeError: 'Like' object is not iterable (Ajax request)

I am not getting a clear picture regarding the Model (Like) object is not iterable.
Error
liked, created = Like.objects.create(question=create_id)
TypeError: 'Like' object is not iterable
model.py
class Question(models.Model):
user = models.ForeignKey(User)
title = models.CharField(max_length= 200)
description = models.TextField()
location = models.CharField(max_length=150)
tags = TaggableManager()
time = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.title
class Like(models.Model):
user = models.ManyToManyField(User, related_name='likes')
question = models.ForeignKey(Question)
date = models.DateTimeField(auto_now_add=True)
likecount = models.IntegerField(default=0)
urls.py
url(r'^like/$', 'apps.question.views.like', name='like'),
views.py
def like(request):
vars = {}
if request.method == 'POST':
user = request.user
tutorial_id = request.POST.get('tutorial_id', None)
create_id = get_object_or_404(Question, id=tutorial_id)
liked, created = Like.objects.create(question=create_id)
try:
user_liked = Like.objects.get(question=create_id, user=user)
except:
user_liked = None
if user_liked:
user_liked.likecount -= 1
liked.user.remove(request.user)
user_liked.save()
else:
liked.user.add(request.user)
liked.likecount += 1
liked.save()
return HttpResponse(simplejson.dumps(vars, user),
mimetype='application/javascript')
template
<button type="button" class="btn btn-request" name="{{question.id}}" id="like">Request</button>
<script>
$('#like').click(function(){
$.ajax({
type: "POST",
url: "{% url 'like' %}",
data: {'tutorial_id': $(this).attr('name'), 'csrfmiddlewaretoken': '{{csrf_token}}'},
dataType: "text",
success: function(response) {
alert('You liked this')
},
error: function(rs, e) {
alert(rs.responseText);
}
});
})
</script>
What I am missing here, can anyone explain me?
Thanks!
Like.objects.create(question=create_id)
Returns a single object (a Like).
So, doing like, created = Like.objects.create(question=create_id) doesn't work because there's only one item on the right, so it can't be unpacked (like if you did like, created = 1).
The method that returns the object and a created boolean object is get_or_create:
like, created = Like.objects.get_or_create(question=create_id)

XHR status returns 0 in ajax call to a django generic view

This is totally weird because I don't know why is returning this error when I replicated the same code for one section to another, only change the title of some generic views (UpdateView) and never execute the get function for return my form for edit a single customer, that's the code:
urls
from django.conf.urls import patterns, include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from . import views
from . import forms
from . import invoice
urlpatterns = patterns('',
url(r'^pedidos/',views.PedidosListView.as_view(),name="pedidos_list"),
url(r'^pedidos/add',views.add_pedido, name="pedido_add"),
url(r'^pedidos/edit/(?P<pedido_id>\d+)',views.edit_pedido, name="pedido_edit"),
url(r'^pedidos/delete/(?P<pedido_id>\d+)',views.delete_pedido, name="pedido_delete"),
url(r'^pedido/(?P<pk>\d+)',forms.DetailPedido.as_view(), name="pedido_detail"),
url(r'^pedido-pdf/(?P<pk>\d+)',invoice.detalle_pedido_pdf, name="pedido_detail_pdf"),
url(r'^clientes/',views.ClientesListView.as_view(),name="clientes_list"),
url(r'^clientes/edit/(?P<pk>\d+)$',forms.ClienteUpdateView.as_view(), name="clientes_edit"),
url(r'^empleados/edit/(?P<pk>\d+)$',forms.EmpleadoUpdateView.as_view(),name="edit"),
url(r'^empleados/',views.EmpleadoListView.as_view(),name="list"),
)
forms
class ClienteUpdateView(UpdateView):
form_class = ClienteModelForm
model = Cliente
template_name = 'ventas/form.html'
def get(self, request, **kwargs):
self.object = Cliente.objects.get(pk=self.kwargs['pk'])
form_class = self.get_form_class()
form = self.get_form(form_class)
context = self.get_context_data(object=self.object, form=form)
return self.render_to_response(context)
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.save()
return HttpResponseRedirect('ventas/clientes_list.html')
def form_invalid(self,form):
if self.request.is_ajax():
return HttpResponseBadRequest(json.dumps(form.errors),
mimetype="application/json")
javascript
$(".edit").click(function(ev){
ev.preventDefault();
var url = $(this).data('form');
$.ajax({
url: url,
success: function(data, status){
$('body').append($('<div id="myModal" class="modal hide fade">' + data + '</div>').modal());
$("#myModal").find(".datePicker" ).datepicker({ dateFormat: "dd/mm/yy" });
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr.status);
console.log(xhr.responseText);
console.log(thrownError);
}
})
return false; // prevent the click propagation
});
html
<button data-form="{% url 'ventas:clientes_edit' c.id %}" class="edit btn btn-mini btn-info">
If in ajax url change the value for 'ventas/empleados/edit/someid' (the same that I replicated for do ClienteUpdateView, I can retrieve the form for employee edit but I can't do the same for customer, I'm missing something that I'm not able now to notice? It's driving my nuts! Any ideas?
Regards!

Django Jquery Get URL Conf

Ok, so I'm trying to call the function
def user_timetable(request, userid):
user = get_object_or_404(TwobooksUser,id = userid)
timeSlots = TimeSlot.objects.filter(user = request.user)
rawtimeslots = []
for timeSlot in timeSlots:
newSlot = {
'userid': timeSlot.user.id,
'startTime': str(timeSlot.startTime),
'endTime': str(timeSlot.endTime),
}
rawtimeslots.append(newSlot)
return HttpResponse(simplejson.dumps(rawtimeslots))
through the javascript in
{% include 'elements/header.html' %}
<script type='text/javascript'>
$(document).ready(function() {
$.get('/books/personal{{ user.id }}/timetable/', {}, function(data) {
data = JSON.parse(data);
var events = new Array();
for (var i in data) {
events.push({
id: data[i].id,
title: '{{ request.user.name }}',
start: Date.parse(data[i].startTime, "yyyy-MM-dd HH:mm:ss"),
end: Date.parse(data[i].endTime, "yyyy-MM-dd HH:mm:ss"),
allDay: false
});
}
where the above exists in a template that's being rendered (I think correctly).
The url conf that calls the function user_timetable is
url(r'^books/personal/(?P<userid>\d+)/timetable/$',twobooks.ajax.views.user_timetable),
But, user_timetable isn't being called for some reason.
Can anyone help?
EDIT-
Ok the original problem was that the template was not being rendered correctly, as the url in firebug comes to '/books/personalNone/timetable/' , which is incorrect.
I'm rendering the template like this -
def renderTimetableTemplate(request):
#if request.POST['action'] == "personalTimetable":
user = request.user
return render_to_response(
'books/personal.html',
{
'user': user,
},
context_instance = RequestContext(request)
)
Is there a mistake with this?
There is a slash missing after "personal"
$.get('/books/personal{{ user.id }}/timetable/', {}, function(data) {
should be
$.get('/books/personal/{{ user.id }}/timetable/', {}, function(data) {
Btw. you should use the {% url %} template tag.
There is a mismatch between the data you're converting to JSON and passing to the script, and the data that the script is expecting. You are passing a userId element in each timeslot, whereas the script is expecting just id.
This error should have shown up in your browser's Javascript console, and would be even easier to see in Firebug (or Chrome's built-in Developer Tools).

Resources