I am writing a custom test case for Django-Mptt template tag . Eveything is working fine but the json I am getting is not valid .
this is the template string I am sending :
self.template = re.sub(r'(?m)^[\s]+', '', '''
{% load yctags %}
[
{% recursetree_custom comments comment_order %}
{
"comment_id": "{{ node.id }}",
"comment_text": "{{ node.text }}",
"comment_parent_id": "{{ node.parent.id }}",
"children": [
{% if not node.is_leaf_node %}
{{ children }}
{% endif %}
]
}
{% endrecursetree %}
]''')
output :
[{"comment_id": "2","comment_text": "2nd comment","comment_parent_id": "","children": [{"comment_id": "7","comment_text": "2nd comment , 2nd child","comment_parent_id": "2","children": []}{"comment_id": "6","comment_text": "2nd comment , ist child","comment_parent_id": "2","children": []}]}{"comment_id": "1","comment_text": "Ist comment","comment_parent_id": "","children": [{"comment_id": "3","comment_text": "Ist comment , ist child","comment_parent_id": "1","children": [{"comment_id": "5","comment_text": "1-1-2","comment_parent_id": "3","children": []}{"comment_id": "4","comment_text": "1-1-1","comment_parent_id": "3","children": []}]}]}]
If u use any json validator for above o/p then u will know about my error in json output , there must be a comma b/w to comments to make it valid.
Please let me know the solution how I can make this json valid
the solution is join comments by comma ','
def _render_node(self, context, node):
# print "node-> ",node
bits = []
context.push()
#print "context->", context
for child in node.get_children():
bits.append(self._render_node(context, child))
context['node'] = node
context['children'] = mark_safe(','.join(bits)) **#join by ,**
rendered = self.template_nodes.render(context)
context.pop()
return rendered
def render(self, context):
queryset = self.queryset_var.resolve(context)
comment_order = self.order.resolve(context)
roots = cache_tree_children(queryset, comment_order)
# print "roots-> ", roots
bits = [self._render_node(context, node) for node in roots]
# print bits
return ','.join(bits) **#join by ,**
Related
I have the below function which returns a list
def get_entered_datalist(firstname, lastname):
if firstname and lastname:
curr = db.session.execute(entered_data, {'firstname': firstname, 'lastname': lastname})
list_name = list() #this is a list contstructor statement so have () brackets, usually when declaring list we use [] brackets
for name in curr:
list_name.append(name)
return list_name
else:
return False
It is being called this way
entered_names = get_entered_datalist(session['v_firstname'], session['v_lastname'])
and passed to the html file this way
return render_template('monthlybudget.html', title='Enter Monthly Budget Data', form=form, entereddata=entered_names)
The display code in HTML file is as below
{% if entereddata %}
{% for x in entereddata %}
<p>{{ x }} </p>
{% endfor %}
{% else %}
<p>No data found</p>
{% endif %}
but it is being displayed with round brackets and quote marks as below
The query getting the values from database is as below
select concat([First Name], ' ', [Last Name] ) as name from [dbo].[EAMonthlyBudget]
where [Report to First Name]= :firstname and [Report to Last Name] = :lastname
and [budget month] = datename(month,getdate()) and [budget year] = year(getdate());
I added a print statement in my python code to check what gets returned by the function and that is as below (shows with the brackets and quote marks)
[12/Aug/2022 15:29:44] "GET /static/images/nu_logo2.png HTTP/1.1" 304 -
[('Janak Shah',), ('Julie Wang',)]
-
How do I display the data without the brackets and quote marks?
Your curr variable contains tuples. try this code:
for name in curr:
list_name.append(name[0])
I think you need to check of index out for range error.
I hope this helps.
I am trying to pass a list called eligable so that I can display on my website but when I run my website it does not display the list. I do not understand what is wrong.
code:
def specificDate(response):
empName = employeeName.objects.all()
eligable = []
if 'checkEmployee' in response.POST:
n = response.POST.get("nameEmployee")
specDate = response.POST.get("date")
if employeeName.objects.filter(employee=n).exists() and Name.objects.filter(date=specDate).exists():
emp = employeeName.objects.get(employee=n)
t = Name.objects.get(name=emp, date=specDate)
overT = Name.objects.filter(name=emp, overtime=True)
for item in overT:
eligable.append(item.date)
checkIn = t.timeIn.strftime("%H:%M:%S")
checkOut = t.timeOut.strftime("%H:%M:%S")
datee = datetime.strptime(specDate,'%Y-%m-%d')
print("Here:: ",t.date)
print("Month:: ",datee.month)
messages.info(response, checkIn + ' - ' + checkOut)
return redirect('/specificDate')
else:
messages.info(response, 'Name does not exist')
else:
pass
return render(response, "main/specificDate.html", context={"empName":empName, "eligable":eligable})
This is the html to print my list:
{% for item in eligable %}
<div class="pad3">
{{item}}
</div>
{% endfor %}
There are two return statements in your code:
return redirect('/specificDate')
and
return render(response, "main/specificDate.html", context={"empName":empName, "eligable":eligable})
The first one is just redirecting without populating context.
The second one does populate context but is reached only when eligable is empty.
I think changing the first return to the second one should solve it.
edit: and you are missing {% endfor %} here. But it should give you an error if you miss it in your complete code.
I've already written a script that parses JSON data from a particular url and stores them into a list. After that I'm able to pass that as an argument to be displayed in my template.
My end goal is to display a table on the template from this JSON data (of which I have currently included only one parameter), for which I believe I need to pass that list into a Django Model.
def index(request):
is_cached = ('raw_json' in request.session)
print(is_cached)
if not is_cached:
# g = {'starttime': '2014-01-01', 'endtime': '2014-01-02', 'minmagnitude': '5'}
g=''
url1 = ul.urlencode(g)
# print(url1)
main_api = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&'
final_url = main_api + url1
# print(final_url)
raw_json = requests.get(final_url).json()
string_json = json.dumps(raw_json)
# print(raw_json)
with open('test.txt', 'w') as file:
file.write(string_json)
count = raw_json['metadata']['count']
print('Count: ' + str(count))
maglist = []
placelist = []
for cou in range(0, count):
mag = (raw_json['features'][cou]['properties']['mag'])
maglist.append(mag)
# magdict = dict(list(enumerate(maglist)))
place = (raw_json['features'][cou]['properties']['place'])
placelist.append(place)
# placedict = dict(list(enumerate(placelist)))
# print(placedict)
with open('test2.txt', 'w+') as t1:
for features in raw_json['features']:
coordinates = (features['geometry']['coordinates'])
id = (features['id'])
t1.write("id: %s \n" % (id))
t1.write("coordinates: %s \n" % (coordinates))
# print(singfeature)
for properties, value in features['properties'].items():
t1.write("%s : %s \n" % (properties, value))
# t1.write("\n")
# print (maglist)
args = {'magni': maglist}
print (args)
return render(request, 'earthquake/index.html', args)
The template receives this data with a simple for loop as follows:
{% block content %}
{% for item in magni %}
<p>{{ item }}</p>
{% endfor %}
{% endblock %}
To which the result shows up as follows:
As mentioned previously, I need to display a filterable/sortable table with this parameter (along with other parameters too), so that the end-user may view the data as needed.
I'm quite new to Django.
There is a file api.yml containing a config for ansible:
config/application.properties:
server.port: 6081
system.default.lang: rus
api.pdd.url: "http://{{ stage['PDD'] }}"
api.policy.alias: "integration"
api.order.url: "http://{{ stage['Order'] }}
api.foo.url: "http://{{ stage['FOO'] }}
There is a stage.yml containing the key and the stage values:
default_node:
Order: '172.16.100.40:8811'
PDD: '172.16.100.41:8090'
FOO: '10.100.0.11:3165
In fact, these files are larger and the 'stage' variables are also many.
My task is to parse api.yml and turn it into properties-config. The problem is that I can not pull up the values {{stage ['value']}} I'm trying to do it this way:
stream = yaml.load(open('api.yml'))
result={}
result.update(stream['config/application.properties'])
context= yaml.load(open('stage.yml'))
stage={}
stage.update(context['default_node'])
text = '{% for items in result | dictsort(true)%} {{ items[0] }} = {{
items[1] }} {%endfor%}'
template = Template(text)
properti = (template.render(result=result, stage=stage))
At the output I get this:
server.port = 6081
system.default.lang = rus
api.pdd.url = http://{{ stage['PDD'] }}
api.policy.alias = integration
api.order.url = http://{{ stage['Order'] }}
api.foo.url = http://{{ stage['FOO'] }}
And you need to get this:
server.port = 6081
system.default.lang = rus
api.pdd.url = 172.16.100.41:8090
api.policy.alias = "integration"
api.order.url = 172.16.100.40:8811
api.foo.url = 10.100.0.11:3165
Can I do it with jinja or ansible lib?
Sorry for my bad english
Following this approach, you would need to treat api.yml as a template itself and render it. Otherwise, jinja2 will treat it as a simple value of the property. Something like this would do:
import yaml
from jinja2 import Environment, Template
import json
stream = yaml.load(open('api.yml'))
result={}
result.update(stream['config/application.properties'])
context= yaml.load(open('stage.yml'))
stage={}
stage.update(context['default_node'])
text = """{% for items in result | dictsort(true)%} {{ items[0] }} = {{ items[1] }} {%endfor%}"""
#Then render the results dic as well
resultsTemplate = Template(json.dumps(result))
resultsRendered = json.loads( resultsTemplate.render(stage=stage) )
template = Template(text)
properti = (template.render(result=resultsRendered, stage=stage))
After this you will see the wanted values in the properti var:
' api.foo.url = http://10.100.0.11:3165 api.order.url = http://172.16.100.40:8811 api.pdd.url = http://172.16.100.41:8090 api.policy.alias = integration server.port = 6081 system.default.lang = rus'
It would be nice though if jinja2 was able to render recursively. Maybe spending some time working out with the globals and shared modes of the Environment this can be achieved.
Hope this helps.
I'm tring to do something like this
{% mytag country "italy" year "2014" %}
workday
{% holyday %}
not workday
{% endmytag %}
But the holyday tag is optional.
This must work too:
{% mytag country "italy" year "2014" %}
workday
{% endmytag %}
I wrote the code
class MytagExtension(Extension):
tags = set(['mytag'])
def __init__(self, environment):
super(TranslateExtension, self).__init__(environment)
def parse(self, parser):
lineno = parser.stream.next().lineno
if parser.stream.skip_if('name:country'):
country= parser.parse_primary()
else:
country= nodes.Const(None)
if parser.stream.skip_if('name:year'):
year = parser.parse_primary()
else:
year = nodes.Const(None)
args = [country, year]
# body1 = parser.parse_statements(['name:holyday']) # not working :)
body = parser.parse_statements(['name:endmytag'], drop_needle=True)
return nodes.CallBlock(self.call_method('_helper', args),
[], [], body).set_lineno(lineno)
def _helper(self, country, year, caller):
etc ....
Is similar to a if else endif, but i didn't find the source code of the if tag (if it exists as Extension)
How can i do this?
Obviously in my _helper I need both the first and second branch because is there that I choose which one to show.
ok, here is an answer, it's not perfect and probably not the best, but it's something.
...
body = parser.parse_statements(
['name:endmytag', 'name:holyday'],
drop_needle=True
)
if not parser.stream.current.test('block_end'):
body.extend ( parser.parse_statements(['name:endmytag'], drop_needle=True) )
args = [
country,
year,
nodes.Const([y.data for x in body for y in x.nodes]), #I don't like this line a lot :)
]
return nodes.CallBlock(self.call_method('_helper', args),
[], [], body).set_lineno(lineno)
...
In this way in the _helper you will receive the third parameter (a list) and choose if return the first or the second element of this list.