Json data not saving in django database Admin - python

I am building a BlogApp and I am trying to access user location through geoplugin BUT it was sending through json so i made a view to send json data to database BUT json data is not saving in Database (Admin).
When i click on link then it is showing :-
'NoneType' object has no attribute 'json'
BUT then i use json.loads then it is showing :-
the JSON object must be str, bytes or bytearray, not NoneType
models.py
class Location(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
city = models.JSONField()
views.py
def jsonLocation(request):
r = request.POST.get('http://www.geoplugin.net/javascript.gp')
# data = json.loads(r)
data = r.json()
for x in data:
title = x["geoplugin_city"]
user = request.user
addin = Location.objects.create(city=title,user=request.user)
addin.save()
return HttpResponse("Successfully submitted!")
I have seen many answers but did't find any solution. And it is still not saving in database.
Any help would be Appreciated.

According to your comments on the post, this should be the error:
You are trying to make a POST-Request to the URL you provided us, doing the following:
def jsonLocation(request):
r = request.POST.get('http://www.geoplugin.net/javascript.gp')
This will not work, request, is an object that describes the INCOMING request of the user loading YOUR webpage. This has a POST-property, from where you can get, e.g. form data.
To make a POST-request and save the data, you will need a Python package for it, I always use Requests, I think it is also the most popular.
Then you would do something along the lines of this:
import requests
r = requests.get('http://www.geoplugin.net/javascript.gp')
data = r.json()
# Continue your script
So, basically, your attempt was good, I think you just mixed up request and requests

Related

Why does django return the data I submitted as the HttpResponse?

So I am making Angular 8 and Django project. The scenario is that from a form in Angular, data is sent to Django to store it in a database.
class NewProfileView(viewsets.ModelViewSet):
queryset = NewProfile.objects.all()
serializer_class = NewProfileSerializer
def post(self,request,*args,**kwargs):
email = request.data['email']
password = request.data['password']
username = request.data['username']
NewProfile.objects.create(email=email,password=password,username=username)
return HttpResponse({'message':'Registered Successfully'},status=200)
The above represents my Django view. Now, seeing this, for a successful creation, I should get the response as 'Registered Successfully'. But what I get is the data I submitted in JSON format (basically a dictionary. I don't really know if it is json).
Why is it happening?
export class PostService {
private url = 'http://localhost:8000/login/';
constructor(private httpClient:HttpClient) {}
getPosts(data){
return this.httpClient.get(this.url+'?email='+data.email+'&password='+data.password);
}
create(url,post){
return this.httpClient.post<any>(url,post);
}
}
This is what is there in my angular service.
onSubmit(){
console.log(this.userForm);
this.service.create('http://localhost:8000/profile/',this.userForm)
.subscribe(response=>{
console.log(response);
});
This is the code in my component.ts file.
P.S.- I know I'm storing the passwords wrong way. But its just for debugging purposes.
To return a dict data from Django should use JsonResponse. This will serializer the Dict into json and add the correct Content-Type header.
from django.http import JsonResponse
>>> response = JsonResponse({'foo': 'bar'})
>>> response.content
>>> b'{"foo": "bar"}' # This will be the body sent to the client
# In your Case
>>> return JsonResponse({'message':'Registered Successfully'},status=200)
On the Javascript side, how you access the JSON data will vary based on the client you use to make http call. You can parse the response body using JSON.parse(body), but most http clients I have used will handle that for you (Fetch API has a response.json() method, and I think axios gives you JS object automatically when the response is json type)
Note on Dict vs JSON
the data I submitted in JSON format (basically a dictionary. I don't really know if it is json).
Dictionary is a native python type. Looks similar to JSON but they are not the same. eg. Python uses None, while JSON uses null, and many other differences like that.
JSON (Javascript Object Notation) is a way to serializer and deserializer javascript objects.
To send a dict data to your JS client as a JSON object, you would need to json.dumps(dict) to get the serialized json version of your dict, and then return that in the response body. JsonResponse handles the serialization for your, and also adds the "Content-Type" headers "application/json" to let your client know it's receiving a json body body that can be deserialized into a JS object.

Python convert python-amazon-simple-product-api results to json using Django

I am writing an API in Python Django and rest framework. I am using a python packaged called python-amazon-simple-product-api to access amazon advertising API. I am trying to feed the results into the rest framework and return the results as JSON Here is my code so far.
class AmazonProductsViewSet(viewsets.ViewSet):
def list(self, request, format=None):
products = amazon.search(Brand="Microsoft", SearchIndex="Software",
ResponseGroup="Images,ItemAttributes,Accessories,Reviews,VariationSummary,Variations")
products = list(products)
With this code I get the following error;
TypeError: Object of type 'AmazonProduct' is not JSON serializable
So I am trying to find a way of making the AmazonProduct object serializable or a better solution.
Not JSON serializable means that your response is an object not a primitive data that can be sent over a network.
You need to write a serializer for that model. Something like this:
class AmazonProductSerializer(serializers.Serializer):
color = serializers.CharField()
title = serializers.CharField()
and use it like this:
products = amazon.search(Brand="Microsoft", SearchIndex="Software", ResponseGroup="Images,ItemAttributes,Accessories,Reviews,VariationSummary,Variations")
data = AmazonProductSerializer(products, many=True).data
return Response(data, status=status.HTTP_200_OK)
Hope it helps!
Probably the best approach is to use the bottlenose [ https://github.com/lionheart/bottlenose ] instead if you just want to get the amazon results as they're and convert to JSON. Here is how I have done it;
amazon = bottlenose.Amazon(access_key_id, secret_key, associate_tag)
class AmazonProductsViewSet(viewsets.ViewSet):
def list(self, request, format=None):
response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
return Response(xmltodict.parse(response)) #json.dumps(xmltodict.parse(response))
Now I get the entire XML document as JSON.

Send user data in python requests module

I am unable to send the user details along with requests module i had to hard code the user details in the data payload to identify the user.
full_url = ''.join(['http://', get_current_site(request).domain, '/am/reply'])
data = {
'agent_type':'trigger',
'input':platform,
'userid':request.user.id ####==>> had to send userid like this
}
a = requests.get(full_url,params=data)
Is there way to send all general request data using requests.?
And moreover the requests url the destination view i have implemented
def index(request):
if not request.user.is_authenticated:
return HttpResponseRedirect(reverse('login'))
And request.user.id is none when url is reached through requests module
In general how should i validate a request when using requests module
Django uses request and response objects to pass state through the system.
When a page is requested, Django creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function. Each view is responsible for returning an HttpResponse object.
Some of the middleware included in Django’s contrib apps set attributes on the request. If you don’t see the attribute on a request, be sure the appropriate middleware class like authenticationmiddleware,sessionmiddleware.
Following piece of code will give the user.id if and only if the user is authenticated.
def myview(request):
if request.user.is_authenticated:
print request.user.id
else:
... # Do something else.
https://docs.djangoproject.com/en/1.10/ref/request-response/
If I understood your question correctly, You are getting request in one view, and then making a call to other view using requests module. It that case the request object in index view will be totally different because that request was sent from your server where application works, not from user. You can only get data in index view using request.GET.get("userid") and so on. And then if you will need user info, just fetch it again from database using userid. Passing request object to other view using requests library is not possible.

Acessing POST field data without a form (REST api) using Django

In the django documentation, it says:
HttpRequest.POST
A dictionary-like object containing all given HTTP POST parameters, providing that the request contains form data. See the QueryDict documentation below. If you need to access raw or non-form data posted in the request, access this through the HttpRequest.body attribute instead.
However, the server does not respond to a browser (such as using JS frameworks or a form) but instead a REST api sent by an Anroid/iOS application.
If the client sends fields directly in a POST request, how can I read the data? For example, this (Java + Unirest):
Unirest.post("/path/to/server")
.field("field1", "value2")
.field("field2", "value2");
EDIT: Can I simply read the data usingresponse.POST["field1"], or will I have to do something with request.body?
EDIT 2: So I can simply use request.body as a dictionary-like object similar to request.POST?
As far as I understand the field method from Unirest just uses normal application/x-www-form-urlencoded data like a HTML form. So you should be able to just use response.POST["field1"] like you suggested.
From the docs:
request.data returns the parsed content of the request body. This is
similar to the standard request.POST and request.FILES attributes
except that:
It includes all parsed content, including file and non-file inputs.
It supports parsing the content of HTTP methods other than POST, meaning that you can access the content of PUT and PATCH
requests.
It supports REST framework's flexible request parsing, rather than just supporting form data. For example you can handle incoming
JSON data in the same way that you handle incoming form data.
Can I simply read the data using response.POST["field1"], or will I
have to do something with request.body?
So I can simply use request.body as a dictionary-like object similar
to request.POST?
An example - From a create method (viewsets):
user = dict(
full_name=request.DATA['full_name'],
password=request.DATA['password'],
email=request.DATA['email'],
personal_number=request.DATA['personal_number'],
user_type=request.DATA['user_type'],
profile_id=request.DATA['profile_id'],
account_id=request.DATA['account_id']
)
Edit 1: In version 3 (latest) - request.DATA has been replaced with request.data:
user = dict(
full_name=request.data['full_name'],
password=request.data['password'],
email=request.data['email'],
personal_number=request.data['personal_number'],
user_type=request.data['user_type'],
profile_id=request.data['profile_id'],
account_id=request.data['account_id']
)
If the api you are interacting with is a sipmle Django Class Based view, you access the data through request.body something like this:
class MyView(View):
def post(self, request):
field1 = request.body.get('field1')
field2 = request.body.get('field2')
... # processing here
In case you are using Django rest framework api, you access the data through request.data:
field1 = request.data.get('field1')
field2 = request.data.get('field2')
NB: If you find request.DATA used somewhere in Internet that's correct too, but it's only valid for old version of DRF, and it's deprecated in favor of request.data in the newer versions.

Django: serialize json as a parameter when redirecting to external url

I am trying to redirect a user to a Facebook app once they login to my Django application. This is happening from inside my view. The Facebook app is expecting a Json encoded variable. Here is what I am trying (which is not working):
json_data = serializers.serialize("json", UserProfile.objects.filter(user=user), fields=('study_code'))
url = "https://www.facebook.com/" + json_data + "some_other_stuff"
return redirect(url)
My question main question: What is the proper way to do this?
One issue I am having is that the "json_data" variable is returning the following:
[{"fields": {"study_code": "XXX001"}, "model": "django_app.userprofile", "pk": 12}]
I thought the 'fields' parameter, in the serialize method, will limit the returned data to only the specified field (I only need the study_code) but I'm getting all of this extra stuff. Also, I can't append the 'json_data' variable to the string 'url' (obviously). What is the correct way to append this serialized data to the url string?

Categories

Resources