I've been having trouble with a query string in one of my views in Django. I've successfully handled query strings in other views, so I'm not sure what I did wrong here. I stripped things down to a really basic view, and I'm still not getting anything.
My URL:
localhost/query_view/?foo=foo
My template:
<html>
<head>
<title>Title</title>
</head>
<body>
<p>{{ query_string }}</p>
</body>
</html>
My view:
def query_view(request):
query_string = request.META['QUERY_STRING']
return render(request, 'query_view.html', {'query_string': query_string})
I should expect foo=foo to be displayed on the page, right? Currently, I'm getting nothing.
Edit: Django version 1.9.4, Python version 3.4.3
try
def query_view(request):
query_string = request.GET.get('foo',None)
print(query_string)
return render(request, 'query_view.html', {'query_string': query_string})
and check if query_string value is None or not .
Let me know, if it didn't work out!
Inaddition mention your django and python version also.
I would put a debugger before the return to see what's actually in the request. But usually something like request.GET.get('foo') would get you what you want. Also, you can provide a default value if foo is actually empty. request.GET.get('foo', 'blah')
Related
I am porting a python / Django application from:
Django==1.5.1
python version 2.6.6
to
Django==3.2
python version 3.6.8
The issue that I am having is that I have a section of code that renders to string, a particular HTML template, and then adds that to list to output elsewhere.
The actual code that produces this HTML is:
class AccountAdmin(SmarterModelAdmin):
list_display = ('username', 'files_url', 'teamMembers', 'roleMemberships', 'safetyLimit', 'admin_quota', 'manager', 'enabled', 'path')
list_filter = ['enabled', 'manager', 'accountType']
search_fields = ['username']
inlines = [RolesInline]
valid_lookups = (
'members__member__username',
'teams__role__username',
)
roles = Account.objects.filter(teams__member=account).order_by('username')
roleList = []
for role in roles:
link = '/admin/files/account/?teams__role__username=' + role.username
# mylink = ''+role.username+''
# linkText = format_html(mylink,myurl=link)
linkText = render_to_string('common/contact.html', context={'URL': link, 'contact': role})
roleList.append(linkText)
return ', '.join(roleList)
roleMemberships.short_description='Roles'
roleMemberships.allow_tags=True```
I have added in a logging.warn to validate what comes out of the render_to_string, and it is straight HTML.
The commented out lines were something that I tried that fixed a similar issue.
common/contact.html is:
<a
href="{{ URL }}"
{% if not contact.enabled %}
style="text-decoration:line-through;"
{% endif %}
>{{ contact.username }}</a>
However, on the final render, It comes out like this:
<a href="/admin/files/account/?teams__role__username=abaumann"
>abaumann</a>,
abaumann
which when run through a browser looks like this:
I haven’t been able to find anything that references this particular issue. I have everything else working in the admin section of the django application, and I am at a loss for why it is not rendering as expected.
Please let me know if there is anything else that you need to see.
I was on the right track, just had an issue with implementation.
Django backend tries to make everything secure. As such, the generated HTML from my template was not considered safe. So, using the mark_safe() function was the key. But where to place it was the challenge.
Anytime the variable containing the HTML is modified IN ANY WAY, the "safe" flag is removed, and the variable is passed through encoding to render any HTML as text.
So the fixe is, on this line:
return ', '.join(roleList)
change it to:
return mark_safe(', '.join(roleList))
My mistake was placing the mark_safe on the linkText variable either at the time the vaiable was set, or when it was appended to the roleList.
I have a script which takes uploaded data, munges it together, turns it into a plot (using Bokeh) and then exports it to a directory as JSON.
At some point in the future, a user can hit the right URL and the appropriate plot should be displayed to the user as part of the HTML template.
I can generate the plot. I can save it as JSON. I can get the URL to retrieve it as JSON, but I cannot get the JSON plot to render within the template.
I've had a dig around the Bokeh documentation and examples, but they all seem to use a flask app to serve the pages.
I think I'm on the right track, using views.py to find and return JSON as part of a render() response, and then have Bokeh.embed.embed_items() do the work in the template to make it look right, but it's not working out - everything but the plot is displayed.
1) Create the plot and puts it in the directory for later use (app/results/1)
create plot.py
import os
import json
from django.conf import settings
from bokeh.embed import json_item
from bokeh.plotting import figure
x=[1,2,3,4,5]
y=[0,-1,-2,3,4]
p=figure(title="test_example")
p.line(x, y)
#json_export = json_item(p, "result")
json_export = json_item(p)
with open(os.path.join(settings.RESULTS_DIR,"1", "test.json"), 'w') as fp:
fp.write(json.dumps(json_export))
2) Set up the url
urls.py
urlpatterns=[
path('result/<int:pk>', views.resultdetailview, name='result-detail'),
]
3) Take the request, use the pk to find the plot json and render it all in the appropriate template.
views.py
def resultdetailview(request, pk):
results=str(pk)
with open(os.path.join(settings.RESULTS_DIR, results, "test.json"), 'r') as fp:
#data=json.load(fp)
data=json.loads(fp.read())
#context={'result':data}
#return render(request, 'app/sandbox_detail.html', context)
return render(request=request,
context={'json_object':data, 'resources':CDN.render()})
NB: If I instead use return JsonResponse(data, safe=False) then the url returns the json successfully ...
I think therefore that the issue is in the template.
4) Show the wonderous plot to the user
sandbox_detail.html
<header>
<link rel="stylesheet" href="http://cdn.bokeh.org./bokeh/release/bokeh-0.11.1.min.css" type="text/css" >
<script type="text/javascript" src="http://cdn.bokeh.org./bokeh/release/bokeh-0.11.1.min.js"> </script>
</header>
<h1> Title: Test </h1>
<div>Test</div>
<body>
<div id="result"></div>
<script>
Bokeh.embed.embed_item({{json_object}}, "result");
</script>
</body>
This template renders everything but the 'result' div.
What have I missed?
This is what I see so far:
FIRST: You are mixing 2 methods for injecting plot json data into the page.
According to documentation you can do it using either of these two methods:
1) specify the div directly:
Python: json_data = json.dumps(json_item(p, "myplot"))
JavaScript: Bokeh.embed.embed_item(item);
2) specify the div in embed_item function:
Python: json_data = json.dumps(json_item(p))
JavaScript: Bokeh.embed.embed_item(item, "myplot");
But not both of them at the same time. Could this be the problem?
SECOND: Preferably don't insert Bokeh resources by hand: rather use CDN.render() or INLINE.render() to automatically include all that your script needs:
import json
from bokeh.resources import CDN
return render(request = request,
template_name = 'app/sandbox_detail.html',
context = { json_object = json.loads(json_string),
resources = CDN.render() } )
sandbox_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{{ resources }}
</head>
<body>
<div id="result"></div>
<script>
Bokeh.embed.embed_item({{ json_object }}, "result");
</script>
</body>
</html>
THIRD: Make sure what you embed in the page is json object not a string (see variable naming above)
It helps when you debug your rendered template in your browser's debug tool.
I tried a very similar approach and found one large flaw: My browser noted that it could not find the None object. The reason here is that python stores the empty value as None, while JavaScript expects a null object.
The solution? Python already translates None to null, when you run json.dumps. To keep it that way, read the json string as a string. So instead of your data=json.loads(fp.read()) use data=fp.read().
So I have a standard Django project with a basic view that returns a simple HTML confirmation statement. Would it be plausible for me to define all of my HTML in the view itself as a really long string and return that using HttpResponse() I know it's a bit unorthodox, but this is an example of what I'm thinking about:
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import render_to_response
def index(request):
html = """
<html>
<body>
This is my bare-bones html page.
</body>
</html>
"""
return HttpResponse(html)
My corresponding JS and stylesheets would be stored in the same directory as views. py in my app in this example. Just making sure: I'm not asking if this works, because I already know the answer is yes, I just want to know if there are any disadvantages/drawbacks to this method, and why don't more people do this?
You can use built-in template renderer to get works filters/templatetags/etc
Most people dont use this because it mixes Python with HTML and gets very messy and out of hand very quickly
To answer your question, this solution works alright, but it is not adopted by many programmers because it makes the whole code disorganized and not easy to understand.
Also, this system would not be good for large projects because the code would contain lots of html in the same file as the python. It is always nice and time saving to separate code into files based on performance.
A better solution
Save your html in a folder called templates in the current directory, in this case, the templates folder can contain an index.html file which would have
<html>
<body>
This is my bare-bones html page.
</body>
</html>
in the views create an index view for this template using the code below
def index(request):
return render(request, 'index.html')
if you would need to pass in some data to the html you can use context in the request as shown below:
def index(request):
context = {
"name":"some name"
}
return render(request, 'index.html', context=context)
access the data in html using the structure below:
<html>
<body>
The data passed to the page is {{name}}.
</body>
</html>
I hope this helps
i have a form in a template, but it can't reach the correspondant view. the method is GET. i've tried also to pass it an argument just to populate the query string, but the request doesnt reach the mapped view. here'sthe views.py, urls.py and the template:
template.html
<div id="search-new-btn">
<form action="/anagrafica/new/" method="get">
<input type="submit" title="Crea nuovo soggetto anagrafica" value="Nuovo" />
</form>
</div>
views.py
def anagrafica_new(request):
if request.method == 'GET':
form = AnagraficaForm()
sub = 'Nuovo soggetto anagrafica'
dict = {'sub':sub,'form':form}
return render_to_response('anagrafica_form.html', dict, context_instance=RequestContext(request))
urls.py
...
url(r'^anagrafica/new/',('gpf1.views.anagrafica_new')),
...
(http://openpaste.org/05b157c1)
Anyway, i've also tried to remove the () from the callback url.py mapping, but it didnt change nothing.
the request seems to be mapped cause my debug server print this:
"GET /anagrafica/new/? HTTP/1.1" 200 17310
but nothing more. the browser remain on the same page; i also put a print statement just inside the view but it never has been reached. any idea?
thanks,
Luke
As Willian suggested don't put the view in a tuple. Another thing you are missing is the $ at the end of regular expression i.e.:
urls.py
...
url(r'^anagrafica/$','gpf1.views.anagrafica'),
...
url(r'^anagrafica/new/$','gpf1.views.anagrafica_new'),
...
Make sure that the folder containing gpf1 package is within Pythonpath variable (reachable by python).
Edit:
Subsequently I noticed you have a root url map for
url(r'^anagrafica/','gpf1.views.anagrafica')
Since you are missing $ at the end Django will try to map anagrafica/anything here to gpf1.views.anagrafica which is probably not what you want. Consider rereading regular expressions and Django's url mapping documentation as it will make things a bit clearer.
I am trying to simply render {{ request.user }} from my base template and for whatever reason it is not rendering anything. I have even tested trying to return {{ request }} to no avail.
I am currently using django-annoying to render to the template (render_to) and have tried to switch back to using django.templates.RequestContext and that hasn't worked either.
I have a feeling it has something to do with caching, but I have edited my template to show test - {{ request }} and "test - " shows up just fine.
I have also tried to upgrade my django to 1.4 alpha to see if it resolves my issue.
This does not send the request to the template
#render_to('profile/index.html')
def home(request):
return {}
This works
#render_to('profile/index.html')
def home(request):
return {'request': request}
However, if I pass 'request': request into the template everything works.
Link to settings.py
I can give any more information that is requested.
You need to add the django.core.context_processors.request context processor.