Django AngularJS JSONResponse view in rendering json output - python

i am developing one of my site with the python django where i have been using angularjs in one of my page where i have given the user option to search (specific request). Here is my model..
class Request(models.Model):
description = models.TextField(blank=True,null=True)
category = models.ForeignKey(Category)
sub_category = models.ForeignKey(SubCategory)
In my views I am returning through the following code:
def some(code, x):
exec code
return x
def search_request(request):
page = request.GET.get('page')
term = request.GET.get('term')
i = 0
terms = "x = Request.objects.filter("
for t in term.split(" "):
i=i+1
if(len(term.split(" "))>i):
terms = terms +"Q(name__icontains='"+t+"')|"
else:
terms = terms +"Q(name__icontains='"+t+"'))"
junk = compile(terms,'<string>', 'exec')
spit = Request.objects.filter(name__icontains=term)
requests = some(junk,spit)
output = HttpResponse()
output['values']=[{'requests':r,'category':r.category,'subcategory':r.sub_category} for r in requests]
return JSONResponse(output['values'])
In my HTML code when I return using AngularJS:
$scope.search = function(){
$scope.results = $http.get("{% url 'search-requests-show' %}?term="+$scope.term).then(
function(result){
return result.data;
}
);
}
The result on the HTML Output comes as in {[{results}]}:
"[{'category': <Category: The New Category>, 'requests': <Request: Need a Table>, 'subcategory': <SubCategory: Testsdfsdfsad>}]"
The problem is that I am not being able to access using results.category because the output is in "string", so the ng-repeat="result in results" brings the result as
[ { ' c a .....
I am probably doing something wrong in view. If anybody has any suggestion then please answer.

JSONResponse is probably using standard python json encoder, which doesn't really encode the object for you, instead it outputs a string representation (repr) of it, hence the <Category: The New Category> output.
You might need to use some external serializer class to handle django objects, like:
http://web.archive.org/web/20120414135953/http://www.traddicts.org/webdevelopment/flexible-and-simple-json-serialization-for-django
If not, you should then normalize object into simple python types inside the view (dict, list, string.., the kind that json module has no problem encoding). So instead doing:
'category':r.category
you could do:
'category': {'name': r.category.name}
Also as a sidenote: using exec is super bad idea. Don't use it in production!

You should return json strings for Angular:
import json
def resource_view(request):
# something to do here
return HttpResponse(json.dumps(your_dictionary))
for better usage i recommend djangorestframework.
Off Topic:
$http.get("{% url 'search-requests-show' %}?term="+$scope.term);
you can pass 'param' object:
$http.get("{% url 'search-requests-show' %}", {param : {term:$scope.term}});

Related

How to index large json response in elasticsearch in python ? using Elasticsearch DSL

I found this approach in the documentation :
https://elasticsearch-dsl.readthedocs.io/en/latest/index.html
class Article(Document):
title = Text(analyzer='snowball', fields={'raw': Keyword()})
body = Text(analyzer='snowball')
tags = Keyword()
published_from = Date()
lines = Integer()
and indexing like
# create and save and article
article = Article(meta={'id': 42}, title='Hello world!', tags=['test'])
article.body = ''' looong text '''
article.published_from = datetime.now()
article.save()
But this approach is not working out for me because I have very large JSON containing fields more than 100, and I have multiple JSON just like that. It would be difficult to convert JSON in this form :
article = Article(meta={'id': 42}, title='Hello world!', tags=['test'])
Any Idea, how to index json directly without model like wrapper?
You should be able to use the dict-structure of json without converting everything to your DSL. Just use the normal elasticsearch client, e.g. see the example for the low level client here: https://github.com/elastic/elasticsearch-py
Please do note that if you have a large number of docs, it is very useful to use the bulk-import API, which can be magnitudes faster.

Django HTTP request to api

So i been trying to get this to work but at the same time i do not understand some of these code means. I'm sorry for making the question so long but i want to understand how these works.
I am trying to make a HTTP request to another API to do POST and GET method using django. Based on the website code example, which is this url: https://www.twilio.com/blog/2014/11/build-your-own-pokedex-with-django-mms-and-pokeapi.html
As i wanted to use HTTP Request on my API to call other API, therefore i wanted to get a better understanding of how these works and how to use it.
The code is at the bottom of the website. But i will just provide the code here so it is easier for you.
website code
from django_twilio.views import twilio_view
from twilio.twiml import Response
import requests
import json
BASE_URL = 'http://pokeapi.co'
def query_pokeapi(resource_uri):
url = '{0}{1}'.format(BASE_URL, resource_uri)
response = requests.get(url)
if response.status_code == 200:
return json.loads(response.text)
return None
#twilio_view
def incoming_message(request):
twiml = Response()
body = request.POST.get('Body', '')
body = body.lower()
pokemon_url = '/api/v1/pokemon/{0}/'.format(body)
pokemon = query_pokeapi(pokemon_url)
if pokemon:
sprite_uri = pokemon['sprites'][0]['resource_uri']
description_uri = pokemon['descriptions'][0]['resource_uri']
sprite = query_pokeapi(sprite_uri)
description = query_pokeapi(description_uri)
message = '{0}, {1}'.format(pokemon['name'], description['description'])
image = '{0}{1}'.format(BASE_URL, sprite['image'])
frm = request.POST.get('From', '')
if '+44' in frm:
twiml.message('{0} {1}'.format(message, image))
return twiml
twiml.message(message).media(image)
return twiml
twiml.message("Something went wrong! Try 'Pikachu' or 'Rotom'")
return twiml
My question is:
i have read about the request.POST and request.POST.get but i still don't get it. Isn't request.POST = POST method/create function ?
what does body.lower mean ? Cant seems to find anything about it.
I am very confuse about this part
sprite_uri = pokemon['sprites'][0]['resource_uri']
description_uri = pokemon['descriptions'][0]['resource_uri']
sprite = query_pokeapi(sprite_uri)
description = query_pokeapi(description_uri)
is pokemon['sprites'] refers to the sprites field in the api ?
What does this even means ?
frm = request.POST.get('From', '')
if '+44' in frm:
twiml.message('{0} {1}'.format(message, image))
return twiml
twiml.message(message).media(image)
return twiml
request.POST.get('From', '') Isn't POST where user enter data ? Where does 'From' come from? And what does this means ? if '+44' in frm: if +44 is found in frm ?
ALL The questions are based on very basic python concepts, I recommend you go through python docs here Python Docs
Diff in request.POST and request.POST.get()
Ex request.post has following dict {'abc_key': 'abc_value'}
than request.POST['abc_key'] will give 'abc_value'
but request.POST['xyz_key'] will throw error
so we use default value to escape this error
request.POST.get('xyz_key', "default_value")
this will not give error if xyz_key is not found
body.lower
This method returns a copy of the string in which all case-based
characters have been lowercased.
check this link lower()
pokemon['sprites'][0]['resource_uri']
this is serching in pokemon (which have dictionary values)
Ex. pokemon = {'sprites':[{'resource_uri': 'res_value'}, 1, 2, 3 ]}
so pokemon['sprites'][0]['resource_uri'] will give 'res_value'
frm = request.POST.get('From', '') same as i said in 1st point
if '+44' in frm:
this will return True if string '+44' is substring in frm
variable(string)

python self.session doesn't save data correctly

I'm developing a webapp using Google App Engine and Python.
I'm facing a strange problem and i don't know how to solve it and what causes it.
When I fill a form I send the data for checking them. If they aren't complete and some fields are missed the server send the form back with an advice "FILL ALL THE FIELDS!".
That's work pretty well.
What I'm trying to do is sending the form back with the "description" and "title" fields filled with what the user has written before submitting the form, so he must to fill only the unfilled fields (and he doesn't need to rewrite everything from the beginning).
That's the code:
class SaleAnnCheck(BaseHandler):
def post(self):
title = self.request.POST.get('title')
cat = self.request.POST.get('cat')
description = self.request.POST.get('description')
AcqOpt = self.request.POST.get('AcqOpt')
lat = self.request.POST.get('lat')
lng = self.request.POST.get('lng')
image1 = self.request.POST.get("file1", None)
image2 = self.request.POST.get("file2", None)
image3 = self.request.POST.get("file3", None)
logging.info("info sale announcment")
logging.info(title)
logging.info(cat)
logging.info(description)
logging.info(AcqOpt)
logging.info(lat)
logging.info(lng)
logging.info(image1)
logging.info(image2)
logging.info(image3)
self.session["ECommerceUser"]["description"]=description
self.session["ECommerceUser"]["title"]=title
logging.info('session')
logging.info(self.session["ECommerceUser"])
if title == '' or cat == None or description == '' or AcqOpt == None or lat == '' or lng == '':
error = 'empty'
urlR='/CreateSaleAnn?'+urllib.urlencode({'error':'empty'})
self.redirect(urlR)
class Create(BaseHandler):
def get(self):
error = self.request.get('error')
if error == 'empty':
logging.info('sbagliato')
logging.info(self.session["ECommerceUser"])
template = JINJA_ENVIRONMENT.get_template('templates/CreateAnnouncement.html')
w = self.response.write
w(template.render({'error':'FILL ALL THE MANDATORY FIELDS!', 'description': self.session["ECommerceUser"]["description"], 'title': self.session["ECommerceUser"]["title"]}))
else:
logging.info('giusto')
logging.info(self.session["ECommerceUser"])
template = JINJA_ENVIRONMENT.get_template('templates/CreateAnnouncement.html')
w = self.response.write
w(template.render({'description': self.session["ECommerceUser"]["description"], 'title': self.session["ECommerceUser"]["title"]}))
When I submit the form the content is checked by making an HTTP post request to a certain URL, handled by SaleAnnCheck.
Description and Title are saved in the session correctly (i checked it by printing the content of self.session["ECommerceUser"] in the logs). Then, if a field isn't filled, the server redirect again to the form page, by a GET request to a related URL.
The requests to that URL is handled by Create. But when i try to render the HTML template of the form (using jinja2) with the previous typed values of Description and Title the related text areas are not filled with that values.
It happens because self.session["ECommerceUser"]["description"] and self.session["ECommerceUser"]["title"] are empty, but they weren't when i checked them before (in SaleAnnCheck).
Why it happens? Any explanation? It's a weird problem and there aren't any tips or suggestion about on internet
This is because 'self.session' is not a Session, it's just a class variable and will not be readable outside the class. If you really want to use persistent sessions for storing variables, try something like this:
From the docs:
http://docs.python-requests.org/en/master/user/advanced/
s = requests.Session()
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get('http://httpbin.org/cookies')

parse a string multiple delimiters returning list of tuples with style and text

I'm trying to parse a string which will have some markdown style delimiters in it. I need a list back with the styles. I've given it a go with pyparsing and have had some success, but feel there is probably a better method (basically using the post by mbeaches at http://pyparsing.wikispaces.com/).
Essentially, if I have a string
word_paragraph = "This is **bold** and this is *italic* sample"
I'd like to return a list of tuples after providing:
style_delim = {'Bold': '**', 'Italics':'*', }
word_pg_parsed = somefunction(word_paragraph,style_delim)
which would result in word_pg_parsed as something like:
word_pg_parsed = [('Normal','This is '),('Bold','bold'),('Normal','and this is '),('Italics','italic'),('Normal',' sample')]
I've looked into markdown, but can't find where this functionality exists. I suspect there is a library (dug into PLY but couldn't find what I am after) that handles this properly.
Why? I'm attempting to create a word file using python-docx file including some text from some marked up text and need to handle the inline character styles accordingly. Is there something in python-markdown or other library anyone has seen that does this?
In the event someone is looking to do this, here's what I found. Many thanks to Waylan for pointing me to mistune and to lepture for the library.
The default_output method was replaced with placeholder. That's the one you need to override to get the list instead of a string. Referenced here: https://github.com/lepture/mistune/pull/20
Basically follow what is in the test case at:
https://github.com/lepture/mistune/blob/878f92bdb224a8b7830e8c33952bd2f368e5d711/tests/test_subclassing.py The getattribute is indeed required, otherwise you'll errors about string functions being called on a list.
Look for TokenTreeRenderer in the test_subclassing.py.
Repeating here in a django views.py for my working sample:
from django.shortcuts import render
from .forms import ParseForm # simple form with textarea field called markup
import mistune
class TokenTreeRenderer(mistune.Renderer):
# options is required
options = {}
def placeholder(self):
return []
def __getattribute__(self, name):
"""Saves the arguments to each Markdown handling method."""
found = TokenTreeRenderer.__dict__.get(name)
if found is not None:
return object.__getattribute__(self, name)
def fake_method(*args, **kwargs):
return [(name, args, kwargs)]
return fake_method
def parse(request):
context = {}
if request.method == 'POST':
parse_form = ParseForm(request.POST)
if parse_form.is_valid():
# parse the data
markdown = mistune.Markdown(renderer=TokenTreeRenderer())
tokenized = markdown(parse_form.cleaned_data['markup'])
context.update({'tokenized': tokenized, })
# no need for a redirect in this case
else:
parse_form = ParseForm(initial={'markup': 'This is a **bold** text sample', })
context.update({'form': parse_form, })
return render(request, 'mctests/parse.html', context)
This results in output of:
[('paragraph', ([('text', (u'This is a ',), {}), ('double_emphasis', ([('text', (u'bold',), {})],), {}), ('text', (u' text sample',), {})],), {})]
which works great for me.

Django Imagekit - how to get the url not in the template?

I have been using django imagekit without any problems in the templates but now I need to get the url in the view not the template, following this example in the imagekit docs:
source_file = open('/path/to/myimage.jpg')
image_generator = Thumbnail(source=source_file)
result = image_generator.generate()
So I did this:
course_img = open(settings.MEDIA_ROOT+str(course.image), 'rb+')
image_generator = myapp_images.Thumbnail100x100(source=course_img)
result = image_generator.generate()
And then, I try to get the url from the "result" variable, but I don't know how:
details_html += "<img class='img-rounded' src='"+ str(result) +"'/>
I have been trying with str(result), result.url, result.name, etc... with no luck, any idea how to get it?
Thx
I got the solution from the imagekit author in the google imagekit group:
In my case I wanted to interact with the Cache File, in order to do that we have to wrap my generator with an ImageCacheFile, like this:
from imagekit.cachefiles import ImageCacheFile
image_generator = myapp_images.Thumbnail00x100(source=course.image)
result = ImageCacheFile(image_generator)
so the result object it is what I was expecting, now I can read the url just using result.url.
Generator itself doesn't allow you to do that on the fly, it generates file-like object, which means it doesn't save the file on disk, which means no filename and so, no URL name..
Either you save the object and generate url manually or you can use ImageCacheFile like this:
from imagekit.cachefiles import ImageCacheFile
file = ImageCacheFile(image_generator, name='my_image.thumb.jpg')
file.generate()
print file.url

Categories

Resources