POST object via Form-Data ( in Django) - javascript

Trying to post the data via multipart (form data) in django backend from react js.
let form_data = new FormData();
let doc = [{ "form" : 1, "city": "Bangalore"}, { "form" : 2, "city": "Delhi"}]
form_data.append("CRegNo", "Nectar00001");
form_data.append("CName", "Nectar");
form_data.append("cityName", doc);
form_data.append("userID", 1);
axios.post("http://127.0.0.1:8000/api/table/", form_data, head)
but in Django it interprets the cityName like this ['[object Object]']
Am I doing something wrong ?

You probably should use JSON.stringify on doc as follows
form_data.append("cityName", JSON.stringify(doc));
Afterwards in your django view you need to parse the data
import json
...
city_name = json.loads(request.POST.get('cityName'))
example using class based views
import json
from django.views import View
class MyView(View):
def post(self, request):
city_name = json.loads(request.POST.get('cityName'))
....

Related

Error in formatting: AttributeError: 'JsonResponse' object has no attribute '_headers'

I am building an app using Django and JavaScript. In Java I have a function that looks like this:
fetch('/posts')
.then(response => response.json())
.then(posts => {
The first line of the JavaScript code actually calls the "post_list" function in my .views
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from .models import Post
#login_required
def post_list(request):
posts = Post.objects.filter(username=request.user)
posts = posts.order_by("-timestamp").all()
return JsonResponse([p.serialize() for p in posts], safe=False)
But then the program crashes in the last line (when I try to return a JsonResponse) and I get a 500 Internal Server Error. As a result I don get a response and my JavaScript .then(response ..... line does not run.
I am not sure If this is relevant to answer the question, but My model looks like this:
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Post(models.Model):
username = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user")
post = models.CharField(max_length=365)
like = models.PositiveIntegerField(default=0)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.username} posted {self.post} the {self.timestamp}, and the post has {self.like} likes"
def serialize(self):
return {
"id": self.id,
"username":self.username,
"post": self.post,
"like": self.like,
"timestamp": self.timestamp.strftime("%b %d %Y, %I:%M %p"),
}
So, does anyone know why I'm getting a 500 Internal server error?
You should not be seeing this error if you import JsonResponse from the correct location. Instead, you should be getting an error "User object is not JSON serializable", which you can fix by doing something like this:
# models.py
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Post(models.Model):
username = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user")
post = models.CharField(max_length=365)
like = models.PositiveIntegerField(default=0)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.username} posted {self.post} at {self.timestamp}, and the post has {self.like} likes"
def serialize(self):
return {
"id": self.id,
"username": {
"username": self.username.username,
"displayName": self.username.get_full_name(),
"lastLogin": str(self.username.last_login.replace(microsecond=0)),
},
"post": self.post,
"like": self.like,
"timestamp": self.timestamp.strftime("%b %d %Y, %I:%M %p"),
}
As some additional advice:
Don't call a user object a username: it becomes confusing when you don't get a username but a full user object
Javascript is fully capable of rendering date formats in a way that make sense to the visitor, so it's preferable to transmit datetimes as ISO-8601 format, which both python and Javascript can handle. I've added that as example for the lastLogin attribute on the user serialization.

Django How to add data to database from javascript

I am have created a page in django, on this page I have create a button that calls a JavaScript function which in turn gets data from a API. This part of my code works as expected as it writes the response data to the console. However I cannot seem to get that data to be inserted into the model I have created in django.
I am not sure how python/javascript/models are meant to all link together.
models.py
from django.db import models
class Set(models.Model):
scry_id = models.CharField(max_length=255)
code = models.CharField(max_length=255)
name = models.CharField(max_length=255)
set_type = models.CharField(max_length=255)
release_date = models.DateField()
card_count = models.IntegerField()
block_code = models.CharField(max_length=255, null=True)
block_name = models.CharField(max_length=255, null=True)
parent_set_code = models.CharField(max_length=255, null=True)
digital_only = models.BooleanField(default=False)
foil_only = models.BooleanField(default=False)
nonfoil_only = models.BooleanField(default=False)
icon = models.CharField(max_length=255)
status = models.BooleanField(default=False)
def __str__(self):
return self.name
sets.html
{% extends "main/index.html "%}
{% block content %}
<div class="background card">
<div class="card-body">
<button class="btn" id="setRefresh" style="border: 1px solid" onclick="setRefresh()"><i class="fas fa-sync"></i></button>
</div>
</div>
{% endblock%}
custom.js
function setRefresh() {
const Url="https://api.scryfall.com/sets";
fetch(Url)
.then(res => res.json())
.then(data => obj = data.data)
.then(() => obj.sort(function(a,b){return a.released_at.localeCompare(b.released_at);}))
.then(() => {
for (var i = 0; i < obj.length; i++) {
//console.log(obj[i].name);
}
})
}
view.py
def sets(request):
return render(request,
"main/sets.html",
{"Sets": Set.objects.all})
There are two missing parts. First you need to have a url to listen for changes and then you need to have a view function where you want to set data. And you need to make some changes for the JS part of your code.Example below can clear this up and it is functional as well:
views.py
#ajax_required
def views_name(request):
try:
if request.method == 'POST':
post_id = request.POST.get('post')
YourModel.objects.create(id=post_id)
except Exception: # pragma: no cover
return HttpResponseBadRequest()
urls.py
urlpatterns = [
url(r'^whatever/$', views.views_name, name='whatever'),
]
custom.js:
$(function () {
$(".class-name").click(function () {
var csrf = $(this).attr('csrf');
var post = $(this).attr('page-id');
$.ajax({
url: '/whatever/',
data: {
'post': post,
'csrfmiddlewaretoken': csrf
},
type: 'post',
cache: false,
success: function (returned_values) {
// do whatever you want after success!
},
});
});
})
There are two ways to do it
Method 1 : After retrieving the data, send them to your django app instead of logging them into the console . have a django view that handles the corresponding request coming from your js code containing the data then adding them to the db. In other words you should fetch again , but this time to your django app using a post request .
.Your view should look like this :
from .models import Set
from django.http import HttpResponse
import json
def save(request):
data=json.loads(request.body)
for entry in data:
s = Set()
s.scry_id=entry["scry_id"]
#in the next lines you map entry fields to Set fields
s.save()
return HttpResponse("ok")
Method 2 : Your button call your django app on click , then your django app retrieve the data from https://api.scryfall.com/sets itself then save them to the db. Your code should look like this
from .models import Set
from django.http import HttpResponse
import json
import requests
def save(request):
response = requests.request("GET", "https://api.scryfall.com/sets")
data=response.json()
for entry in data:
s = Set()
s.scry_id=entry["scry_id"]
#in the next lines you map entry fields to Set fields
s.save()
return HttpResponse("ok")
Of course in either case don't forget to map your urlconf to the save view

How to retrieve post data from view of django app

All I am new to jquery and Django.
I used the following code to post when the button with id 'submit_data' is clicked. Is it possible to retrieve the dictionary { data_key: 'myString'} from the views.py of the Django app?
If yes how?
$(function() {
$('#submit_data').on('click',function() {
$.post('/url/', { data_key: 'myString'}, function(result) {
alert('successfully posted');
});
});
});
For a POST request with form data, you can use request.POST:
def my_view(request):
print(request.POST)
# ...
For a POST request with JSON data, you need to decode request.body:
import json
def my_view(request):
# TODO: missing a suitable `content-type` header check
data = json.loads(request.body.decode())
print(data)
# ...
request.data is used to fetch data from your frontend
it is a dictionary-like object that lets you access submitted data by key name.
Try this:
request.data.get('data_key',None).
To avoid KeyError, you can use .get() which provides value if key found else None is returned.
In template script
$(function() {
$('#submit_data').on('click',function() {
$.post('/url/', { 'data_key': 'myString'}, function(result) {
alert('successfully posted');
});
});
});
in views.py
if request.method == 'POST':
data = request.POST.get('data_key', None)

In Django, how to render both JSON data with api and info from context dictionary

In Django, I want to render a page that includes a Chart js chart that relies on data from my database. I believe I need to implement an API for this. The same page with the chart will contain other info from the database that I think is rendered with a context dictionary and {{ variable }}. I know how to do one or the the other, but not both on the same page. Here is what I have so far. In views.py:
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from django.views import generic
from django.views.generic import View
from .models import Article
from rest_framework.views import APIView
from rest_framework.response import Response
class ChartData(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
articles = Article.objects.all()
correlationlist = []
nocorrelationlist = []
for corr in articles:
if corr.correlation_type == "Correlation":
correlationlist.append(1)
nocorrelationlist.append(0)
elif corr.correlation_type == "No Correlation":
correlationlist.append(0)
nocorrelationlist.append(1)
else:
pass
correlation_items = correlationlist
nocorrelation_items = nocorrelationlist
data = {
"correlation_items": correlation_items,
"nocorrelation_items": nocorrelation_items,
}
return Response(data)
The Javascript I have on the page where the chart appears is:
$(document).ready(function(){
var endpoint = 'api/chart/data/'
var defaultData1 = []
var defaultData2 = [];
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
defaultData1 = data.correlation_items
defaultData2 = data.nocorrelation_items
setChart()
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
function setChart(){
CHART js code goes here
}
})
But on the page where the chart appears, I also want to include other information from the data base, such as:
The title of the article is: {{ title }}
To do this and to render the page, I think I need to create a function in views as follows:
def results(request):
myresults = Article.objects.all()
context = {'myresults': myresults}
return render(request, 'my_page_with_results_and_chart.html', context)
In short, how do you render a page that pulls data from an API for a chart, but also gets database information from the render(request, 'page.html', context) method? This is driving me crazy.
not really sure what you're asking, seems very ambiguous. From a glance it looks like, myresults = Article.objects.all() and articles = Article.objects.all() are the same and you just want to get the title from the article?
Just add articles into your data dictionary
data = {
"myresults": articles,
"correlation_items": correlation_items,
"nocorrelation_items": nocorrelation_items,
}
then just reference it in your html. You cant just do {{ title }} though like your example as 'title' is not a key to your dictionary. if 'articles' is a dictionary with title as a key, you'll need to do {{ myresults.title }} in the html. I hope i answered your question :/
I'm not sure if this is what you're asking as it seems too basic but just from your examples it looks like you are..? Anyway if you do need to make an api the Django RESTful library is really good and great documentation http://www.django-rest-framework.org/

Can not parse json object when using templateHTMLrenderer in django

I'm beginning with django and JSON and I'm trying to send the list of patients in JSON using the code bellow:
class JSONResponse(HttpResponse):
"""
An HttpResponse that renders its content into JSON.
"""
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
#api_view(('GET',))
#renderer_classes((TemplateHTMLRenderer,))
#csrf_exempt
def patient_list(request):
"""
List all records, or create a new snippet.
"""
if request.method == 'GET':
#data = Patient.objects.all()
data= Patient.objects.all()
#serializer = PatientSerializer(data, many=True)
#return JSONResponse(serializer.data)
return Response({'patients': data}, template_name='records.html')
In records.html, I have this javascript code:
<script type="text/javascript">
var data = "{{patients}}";
var parsed = JSON.parse(data);
</script>
...
<h2> <script type="text/javascript">document.write(data);</script></h2> This is not actually true, I'm trying to figure out how to do it
However, when printing data (in string just to see what I have) I'm receiving something like that
[<Patient: Patient object>, <Patient: Patient object>, <Patient: Patient object>, <Patient: Patient object>, <Patient: Patient object>, <Patient: Patient object>, <Patient: Patient object>]
From my understanding it is not necessary to serialize data when using Response so I did not do it. I just want to get the list of patients and print their firstName for instance. Any help about that ?
You should probably just use the JsonResponse class that Django provides if you want to do it the long way: https://docs.djangoproject.com/en/1.9/ref/request-response/#jsonresponse-objects. But since it looks like you're using DjangoRestFramework, in that case, you might want to consider just making a serializer class and then just making a ViewSet.
in seralizers.py:
from rest_framework import serializers
class MySerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
in views.py:
from rest_framework import viewsets
from .serializers import MySerializer
class MyViewSet(viewsets.ModelViewSet):
serializer_class = MySerializer
queryset = MyModel.objects.all()
in urls.py:
from rest_framework import routers
from .views import MyViewSet
router = routers.SimpleRouter()
router.register(r'mymodel', MyViewSet)

Categories