Sending localized messages to Django users - django

I'm having trouble with sending localized messages to Django users using the
user.message_set.create(message="Message")
mechanism. First of all,
user.message_set.create(message=_("Message"))
flat out doesn't work, SQLite says it won't accept the non-ascii parameter (localized message contains special characters).
user.message_set.create(message=unicode(_("Message")))
sends the original English message regardless of the preferred language (other translated parts of the app do work correctly).
Using a hardcoded localized message like this
user.message_set.create(message=u"Localized message áýčš")
is the only thing that works but that implies that I'd be able to only use one language.
How can I send users localized messages loaded from LC_MESSAGES?

Have you tried localizing the message right before you display it?
In your view:
user.message_set.create(message="Message")
In your template
{% if messages %}
<ul>
{% for message in messages %}
<li>{% trans message %}</li>
{% endfor %}
</ul>
{% endif %}
This way, you don't have to store any odd characters in your database.

user.message_set.create(message=_("Message"))
... should work. Are you using the latest version of SQLite, does UTF-8 support have to be enabled somehow? Are you storing non-ascii characters in SQLite elsewhere?

Related

Django messages: How do I remove floating message header on top of the page?

Using django messages automatically creates a header on the top of my page.
views.py
messages.error(request, 'Requested break is overlapping')
Does anyone know how to remove the message header? I have figured out how to place messages around my site but I can't get rid of the one on the top of my page, which is messing with my already existent nav bar header.
If I understand correctly... this depends entirely on how you print the messages in your template.
If your code looks like
<div id="messages">
{% for message in messages %}...{% endfor %}
</div>
the div, however much space it might take up, will naturally be always printed, regardless if there are messages or not.
You can wrap the <div> in {% if messages %}...{% endif %} to avoid this.

django form errors. get the error without any html tags

I would like to get on my template the errors of the form in non-html version.
by default the error is wrap up by <ul class="errorlist"> which I want to avoid.
Anyway to do it without a massive code change ?
There are two new methods in Django 1.7 that would also be useful to solve this problem:
Form.errors.as_data()
>>> f.errors.as_data()
{'sender': [ValidationError(['Enter a valid email address.'])],
'subject': [ValidationError(['This field is required.'])]}
Form.errors.as_json()
>>> f.errors.as_json()
{"sender": [{"message": "Enter a valid email address.", "code": "invalid"}],
"subject": [{"message": "This field is required.", "code": "required"}]}
This section in the forms documentation section has all the details, namely this snippet:
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
Replace form with whatever you call your form class in the template. In this example, subject is a field in the form. If you want to have a separate section to summarize all the errors, simply loop through the fields:
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
{{ error|escape }}
{% endfor %}
{% endfor %}
{% endif %}
Updated for Django 2.1
We have 4 options to access form errors in views.
Form.errors
Access the errors attribute to get a dictionary of error messages:
f.errors
{'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}
In this dictionary, the keys are the field names, and the values are lists of strings representing the error messages. The error messages are stored in lists because a field can have multiple error messages.
You can access errors without having to call is_valid() first. The form’s data will be validated the first time either you call is_valid() or access errors.
The validation routines will only get called once, regardless of how many times you access errors or call is_valid(). This means that if validation has side effects, those side effects will only be triggered once.
Form.errors.as_data()
Returns a dict that maps fields to their original ValidationError instances.
f.errors.as_data()
{'sender': [ValidationError(['Enter a valid email address.'])],
'subject': [ValidationError(['This field is required.'])]}
Use this method anytime you need to identify an error by its code. This enables things like rewriting the error’s message or writing custom logic in a view when a given error is present. It can also be used to serialize the errors in a custom format (e.g. XML); for instance, as_json() relies on as_data().
The need for the as_data() method is due to backwards compatibility. Previously ValidationError instances were lost as soon as their rendered error messages were added to the Form.errors dictionary. Ideally Form.errors would have stored ValidationError instances and methods with an as_ prefix could render them, but it had to be done the other way around in order not to break code that expects rendered error messages in Form.errors.
Form.errors.as_json(escape_html=False)
Returns the errors serialized as JSON.
f.errors.as_json()
{"sender": [{"message": "Enter a valid email address.", "code": "invalid"}],
"subject": [{"message": "This field is required.", "code": "required"}]}
By default, as_json() does not escape its output. If you are using it for something like AJAX requests to a form view where the client interprets the response and inserts errors into the page, you’ll want to be sure to escape the results on the client-side to avoid the possibility of a cross-site scripting attack. It’s trivial to do so using a JavaScript library like jQuery - simply use $(el).text(errorText) rather than .html().
If for some reason you don’t want to use client-side escaping, you can also set escape_html=True and error messages will be escaped so you can use them directly in HTML.
Form.errors.get_json_data(escape_html=False) [new in django 2.0]
f.errors.get_json_data(escape_html=False)
Returns the errors as a dictionary suitable for serializing to JSON. Form.errors.as_json() returns serialized JSON, while this returns the error data before it’s serialized.
The escape_html parameter behaves as described in Form.errors.as_json().
To access errors for a certain field, use form.field_name.errors, where "field_name" is the name of the field that generates the error.
It is still good to use a for loop, in case more than one error was generated in the field.
Crude example:
{% for error in form.email.errors %}
<label>{{ error|escape }} </label>
{% endfor %}
<br>
<label>Email: </label>{{ form.email }}
Some errors may not be specifically related to a certain field, for example, an error that is raised when two password fields do not match. They should be accessible by:
{{ form.non_field_errors }}

Django: Allow user to submit valid HTML in form field

With Django, is it possible for users to submit HTML in a form field, save it, and then render the HTML in the template?
An example is a user adding a link within a textfield that should then be rendered as an a tag within the rest of the text.
The user would input something like :
this is a site called SO.
The SO link would be a link instead of rendering it as text.
Django escapes by default. You can mark a string as safe via a filter or tag to prevent the auto escaping behavior.
{{ my_text_with_html|safe }}
{% autoescape off %}
{{ my_test_with_html }}
{% endautoescape %}
If you accept user inputted html, you'll want to sanitize it so they can't write scripts and such.. for that, just search python html sanitizing and apply it before sending the data to the template.
Python HTML sanitizer / scrubber / filter
You can tell Django the HTML is safe by marking it with the appropriate filter:
{{ variable|safe }}
You can also use the autoescape tag to disable the autoescaping:
{% autoescape off %}
{{ variable }}
{% endautoescape %}
However, in case you are enabling this feature for other (unknown) users, I highly recommend using something else, since HTML can be quite a pain to properly sanitize from Javascript or other HTML-things you don't want (e.g., on*-arguments etc). Django actually ships with basic support for some markup languages you can provide to your users. I guess markdown is being the most popular.

Infinite scroll in django

Is it possible to implement facebook style loading of content while scrolling down? I would like to implement it in an ecommerce site. There are a lot of items in each category and the category page becomes too long. I could implement page numbers but my client wants me to implement that facebook type of loading. Is there anything I can use? Rest of the site has already been built.
I did look into django-endless-pagination but was not able to get it to work. Is there any demo of it so that I can look into it?
We used django endless pagination on www.mymommemories.com without too much problem. Because we were using html5media we did have to add a line to run that function with a one second delay. (setTimeOut("html5media()", 1000). Running it without the delay caused problems in some browsers. If your not using html5media, this should not be a concern however.
Core part of the template code.
{% load endless %}
{% paginate memories %}
{% for memory in memories %}
.
.
.
{% endfor %}
{% show_more %}
In the view we have the following to handle the ajax request.
if request.is_ajax():
template = page_template
return render_to_response(template,context,context_instance=RequestContext(request))
The page_template is not the whole page, just the portion related to the "paging".
I thinks the easiest way to do endless pagination is use jQuery (use $.loads).
You even don't need change the back-end code.
http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/
Perhaps take a look at that?

How to disable autoescape in django feeds?

I use django feed framework to organize rss feeds for my website.
I need to put some hyperlinks to feed items, but al of them are
autoescaped ( "<" is replaced with "<" and so on).
Is it possible to keep tags in my feed (as I understand, I can't use
{% autoescape off %} tag in feed templates)?
Thanks.
Read up on Automatic HTML escaping in Django and try the following syntax. Where data is the variable which holds your link
{{ data|safe }}
As jitter mentioned you can use "safe" filter, but it's annoying if you want to disable autoescaping often. Django also supports {% autoescape off %} {% autoescape end %} blocks, everything inside is block won't be autoescaped.
EDITED: Sorry, I haven't read your question completely only title :). Why you can't use autoescape tag in feeds? There's no restriction about it.