I'm trying to render a variable that will update multiple time in the code, but it just renders the last one to the template,
for example on :
views.py:
def test(request):
message = 'first massage'
#do something
message = 'second massage'
return render(request,'test.html',{'message':message})
test.html :
<h1> {{message}} </h1>
It only displays the second message, but I want it to display the first message then after it changed, display the second message. Any help ?
If you want to change your 'message' variable dynamically ( like 'message' variable has something to do with your models),
a.)Update your 'message' variable using python in views.py,
Create an api which returns JsonResponse.Then you can fetch this data through
JavaScript and update (document.getElementById("someID").innerHTML=``${message}`)
in Views.py
def testapi(request):
# do something
return JsonResponse({"message":"VALUE_OF_MESSAGE"},status=201)
in javascript file
fetch('/testapi')
.then(response => response.json())
.then(resp => {
console.log(resp); //output=> {"message":"VALUE_OF_MESSAGE"}
var message=resp.message;
document.getElementById('someId').innerHTML= ``${message}`;
});
You can perform fetch request whenever you want to and any number of times.
2.)If you have to do something with elements in the page to update your message
variable, I recommend you to use JavaScript directly.
Hello I think you can solve it by doing the following....
You need to create a loop.. it will look something like this..
Before your html code type in {% for message in messages %}
And after your html code type in {% endfor %}
Hopefully it works....
Related
New Programmer Here
So I'm working on a contact form and when I click send I want a message to appear and disappear.
The problem is if some fields were left empty I obviously wouldn't want to show the message because it didn't actually send.
So I was trying to only show the message if the server makes a POST request as opposed to a GET
request because then I know the information was actually stored.
Therefore I used the "post" variable in my html, used jquery to target it and store it in the variable method. But for some reason the if statement isn't being triggered when the the variable "method" does equal "POST"
Tried to explain as best as possible as this is my first time posting.
I know the method value is "POST" when I hit send because it populates on html and I get an alert saying POST
Python Code
#app.route("/contact" , methods=['GET', 'POST'])
def contact():
meth = request.method
return render_template("contact.html",page=x, post=meth)
HTML CODE
<div id="method">
{{post}}
</div>
<div class="submit-message">
<p class="message">THANKS FOR YOUR MESSAGE! </p>
</div>
JS Code
$(document).ready(function(){
var method = $("#method").html();
$("#method").hide();
alert(method)
if (method == "POST"){
$(".message").show();
alert(method);}
else{
$(".message").hide();
}
});
I'm trying to update a database value called ''favorites'' for the logged in user of a Flask web app using a button click. Essentially, the favorites column is a single string that looks like this: Apples, Bananas, Oranges where on the button click, I would want to append a value (say Cherries) by breaking apart the string into a list in my #app.routes(), appending the value, and rejoining it back into a string before committing the changes. I'm not sure what the proper way is to do this, here's what I have:
HTML snippet
<button action="{{ url_for('add') }}" method="post" type="submit">Favorite</button>
#app.routes()
#app.route('/add', methods=['POST'])
def add():
star_faves = current_user.favorites
star_faves_list = star_faves.split(', ')
star_faves_list.append('Cherries')
', '.join(star_faves_list)
current_user.favorites = star_faves_list
db.session.commit()
return render_template('add.html')
The problem is that I don't really understand how the HTML is communicating with Python/Jinja, if anybody can help clear that up I would greatly appreciate it.
It looks like you have some elements confused.
If you want to submit a POST request to the /add page, the easiest way is to create a form. (Buttons do not have an action or method attribute, forms do.) When you create the form, you also specify the HTTP method to use when submitting the form. So in your case, it should look something like this:
<form action="{{ url_for('add') }}" method="POST">
<input type="submit" value="Favorite">
</form>
You can use a button instead of an input with type submit, they are interchangeable.
If you don't want the page to reload while submitting the request, a more advanced technique you can use with JavaScript is something called AJAX.
This example code sends the same POST request to the /add page:
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
// this method gets called if the state of the request changes (it succeeds of fails)
// you will probably want to update your page accordingly here
};
request.open('POST', '/add');
request.send();
Sorry in advance if there is an obvious answer to this, I'm still learning the ropes with Django.
I'm creating a website which has 6 pre determined subjects (not stored in DB)
english, civics, literature, language, history, bible
each subject is going to be associated with a unique color.
I've got a template for a subject.html page and a view that loads from the url appname/subject/subjectname
what I need to do is apply particular css to style the page according to the subject accessed. for example if the user goes to appname/subject/english I want the page to be "themed" to english.
I hope I've made myself clear, also I would like to know if there is a way I can add actual css code to the stylesheet and not have to change attributes one by one from the back-end.
thanks very much!
In templates you can use conditionals for add css, like this:
<div class="{% if subject=='civics' %}civic-class{% endif %}"></div>
For this, subject value should come from view.
Now, for themed page, you could use the extends tag. Let's supose:
def your_view(request):
subject # Here you get the url subject, 'how' is up to you
if subject == 'english'
template_base = '/some/html/tenplate.html'
elif subject == 'civis':
template_base = '/some/other/template.html'
... # then you return 'template_base' variable to template
Then in template:
{% extends template_base %} # at the top
Hope this helps, is the same logic if you use Class-Based views.
Django's views are not responsible for the presentation, it's the template (and css etc of course)'s reponsability. Now assuming you have the same view serving different subjects, the view obviously need to know which is the current subject (I assume from a captured part of the url passed as argument to the view), so it can easily pass this information to the template, which in turn can use it to add a subject-specific class to the body tag. Then you only have to write your css accordingly.
As an example:
# urls.py
patterns = urlpatterns('',
#...
url(r'whatever/(P?<subject>[a-z-]+>)/$', 'myviews.index', ...),
)
# myviews.py
def index(request, subject):
# do whatever
context = {
# whatever else
'subject':subject
}
return render(request, "whatever/index.html", context)
# whatever/index.html
<html>
# headers etc
<body class="something {{ subject }} etc">
# whatever here
</body>
</html>
You can do this is many ways.
In general you need to return some variable from your view to the html and depending on this variable select a style sheet, if your variable name will match you style sheet's name you can do "{{variable}}.css", if not you can use JQuery.
I'm writing a twitter-like note-taking web app.
In a page the latest 20 notes of the user will be listed,
and when the user scroll to the bottom of the browser window more items will be loaded and rendered.
The initial 20 notes are part of the generated html of my django template, but the other dynamically loaded items are in json format.
I want to know how do I do the tag-and-username converting consistently.
Thanks in advance.
There's a couple of pieces to consider here. On the server side, you have to be able to maintain what "chunk" of the notes list the user is on. The easiest way to do this is probably the Django paginator. It works basically by taking a QuerySet, setting a count for the number of items, then giving it the "page" number (or "chunk" number) and it returns those items.
You could do it with JSON, but it would be just as easy to do it with HTML as well. When we look at the client side part of this you'll see why.
So we can have a view "api" to handle a note "chunk" (note all my code samples here are abbreviated just for demonstration. You'd want to have error handling and all that)...
def get_notes_chunk(request, *args, **kwargs):
# Get our notes, however...
all_notes = Notes.objects.all()
# Paginate them based on the page we're on...
chunk_number = request.GET.get('c')
paginator = Paginator(all_notes, 20) # (show 20 at a time)
current_chunk = paginator.page(chunk_number)
# Render to template all that jazz
render_to_template( ... , { 'paginator':paginator, 'current_chunk':current_chunk }, ...)
Our template renders <li> tags which we'll stick into a <ul> on the client...
{% for note in current_chunk.object_list %}
<li>{{ note }}</li>
{% endfor %}
Now on the client, we need to write some javascript to handle this. It's up to you to determine on what event to fire the update, but as for how, we can use a little jQuery to handle this...
<script type="text/javascript">
var chunk_count = 1;
var notes_list_id = 'notes-list'
function load_next_chunk() {
chunk_count += 1;
$.get('{% url get_notes_chunk %}?c=' + chunk_count, function(html) {
$('#'+notes_list_id).append(html);
});
}
</script>
<body>
...
<ul id="notes-list">
<!-- Render chunk #1 here -->
</ul>
...
</body>
Some things that would probably make sense...
Refactor the rendering of the notes list into a template tag so that you can re-use it for your API and the main rendering of your page
Refactor the querying/paginating of the Notes (or whatever) model so that you can re-use it in both views
Figure out on what event the next chunk will be loaded and implement that.
The question isn't that clear... but for generating the HTML out of a Tweet take a look at twp(based on the official twitter-text-java lib):
http://github.com/BonsaiDen/twp
I'm not sure exactly what you're asking, but what's wrong with something like {{ user.get_absolute_url }}? For the tag detail URLs, it really depends on what you're looking for, but you would have to construct the url and view for that yourself.
I have a view that accepts a form submission and updates a model.
After updating the model, I want to redirect to another page, and I want a message such as "Field X successfully updated" to appear on this page.
How can I "pass" this message to the other page? HttpResponseRedirect only accepts a URL. I've seen this done before on other sites. How is this accomplished?
This is a built-in feature of Django, called "messages"
See http://docs.djangoproject.com/en/dev/topics/auth/#messages
From the documentation:
A message is associated with a User.
There's no concept of expiration or
timestamps.
Messages are used by the Django admin
after successful actions. For example,
"The poll Foo was created
successfully." is a message.
You can use django-flashcookie app
http://bitbucket.org/offline/django-flashcookie/wiki/Home
it can send multiple messages and have unlimited types of messages. Lets say you want one message type for warning and one for error messages, you can write
def simple_action(request):
...
request.flash['notice'] = 'Hello World'
return HttpResponseRedirect("/")
or
def simple_action(request):
...
request.flash['error'] = 'something wrong'
return HttpResponseRedirect("/")
or
def simple_action(request):
...
request.flash['notice'] = 'Hello World'
request.flash['error'] = 'something wrong'
return HttpResponseRedirect("/")
or even
def simple_action(request):
...
request.flash['notice'] = 'Hello World'
request.flash['notice'] = 'Hello World 2'
request.flash['error'] = 'something wrong'
request.flash['error'] = 'something wrong 2'
return HttpResponseRedirect("/")
and then in you template show it with
{% for message in flash.notice %}
{{ message }}
{% endfor }}
or
{% for message in flash.notice %}
{{ message }}
{% endfor }}
{% for message in flash.error %}
{{ message }}
{% endfor }}
I liked the idea of using the message framework, but the example in the django documentation doesn't work for me in the context of the question above.
What really annoys me, is the line in the django docs:
If you're using the context processor, your template should be rendered with a RequestContext. Otherwise, ensure messages is available to the template context.
which is incomprehensible to a newbie (like me) and needs to expanded upon, preferably with what those 2 options look like.
I was only able to find solutions that required rendering with RequestContext... which doesn't answer the question above.
I believe I've created a solution for the 2nd option below:
Hopefully this will help someone else.
== urls.py ==
from django.conf.urls.defaults import *
from views import *
urlpatterns = patterns('',
(r'^$', main_page, { 'template_name': 'main_page.html', }, 'main_page'),
(r'^test/$', test ),
== viewtest.py ==
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
def test(request):
messages.success( request, 'Test successful' )
return HttpResponseRedirect( reverse('main_page') )
== viewmain.py ==
from django.contrib.messages import get_messages
from django.shortcuts import render_to_response
def main_page(request, template_name ):
# create dictionary of items to be passed to the template
c = { messages': get_messages( request ) }
# render page
return render_to_response( template_name, c, )
== main_page.html ==
{% block content %}
{% if messages %}
<div>
{% for message in messages %}
<h2 class="{{message.tag}}">{{ message.message }}</h2>
{% endfor %}
</div>
{% endif %}
{% endblock %}
I have read and checked all answers, and it seems to me that the way to go now is using the messaging framework. Some of the replies are fairly old and have probably been the right way at the time of the posting.
There is a lot of solutions
1 Use Django-trunk version - it support sending messages to Anonymous Users
2 Sessions
def view1(request):
request.session['message'] = 'Hello view2!'
return HttpResponseRedirect('/view2/')
def view2(request):
return HttpResponse(request.session['message'])
3 redirect with param
return HttpResponseRedirect('/view2/?message=Hello+view2')
4 Cookies
Can you just pass the message as a query param oon the URL to which you're redirecting? It's not terribly RESTy, but it ought to work:
return HttpResponseRedirect('/polls/%s/results/?message=Updated" % p.id)
and have that view check for a message param, scrub it for nasties, and display it at the top.
I think this code should work for you
request.user.message_set.create(message="This is some message")
return http.HttpResponseRedirect('/url')
Take a look at Django's messages framework. http://docs.djangoproject.com/en/dev/ref/contrib/messages/#ref-contrib-messages
You could also have the redirect url be the path to an already parameterized view.
urls.py:
(r'^some/path/(?P<field_name>\w+)/$', direct_to_template,
{'template': 'field_updated_message.html',
},
'url-name'
),
views.py:
HttpResponseRedirect( reverse('url-name', args=(myfieldname,)) )
Note that args= needs to take a tuple.
The solution used by Pydev UA is the less intrusive and can be used without modifying almost nothing in your code. When you pass the message, you can update your context in the view that handles the message and in your template you can show it.
I used the same approach, but instead passing a simple text, passed a dict with the information in useful fields for me. Then in the view, updated context as well and then returned the rendered template with the updated context.
Simple, effective and very unobstrusive.
While all suggestions so far work, I would suggest going with Ry4an's (pass it in the request URL) - just change the actual text to a coded text within a predefined set of text messages.
Two advantages here:
Less chance of something hacking through your scrubbing of bad content
You can localize your messages later if needed.
The other cookie related methods.. well, they don't work if the browser doesn't support cookies, and are slightly more expensive.. But only slightly. They're indeed cleaner to the eye.