Django Form Name as Attribute in HTML Template - django

I have an attribute of objects that can be rendered in html template like this :
{{ mymodels.something }}
In my case, i have forms containing an input field that has name similar with "something", so i want to run something like this in my template:
{% for form in my_form %}
{{ mymodels.form.name }} <!-- is same as mymodels.something -->
{% endfor %}
but it can't be rendered..
How can i do something like that?

Forms are something to gather data on client side - send it over to server side which validates them and does something with them (e.g. writing into models, or maybe passing it back into the context of your next rendering).
When your template is rendered, it also renders your form (building the markup, providing initial values) - when the template engine finished it's job, the HTML code is sent to the browser.
If you want to access form data on rendering time, there will always be the same value: the initial value. Which does not make much sense. As you might just pass the same data to your rendering context and use it from there.
Read the docs for further information on forms, especially the part rendering fields manually might interest you - if your question aims into this direction.

Related

How can one create a custom "as_table()" method for forms?

I have a relatively complicated form that's used in multiple places on my website (in fact, it's a form from which many other form classes inherit). In the templates, the inherited part of this form is always formatted identically—but that formatting is somehwat involved; each field is rendered and positioned manually in the template.
This means that every template which displays this form has a lot of identical HTML markup that renders the form appropriately.
I would like to create a custom output that can be called, similar to the as_table() methods. I'm aware that one can override the normal_row, error_row, etc. attributes—but the formatting of this form goes beyond that (for example, three of the form's five fields should be printed side-by-side, with a combined title). All of the tutorials/answered-questions I've seen either refer to overriding the above-mentioned attributes, or give instructions on how to manually render forms.
Originally, I was thinking something like this:
Class StrangeForm(form.Forms):
....
def as_table_custom():
html_string = "\
<tr><td>Title 1:</td><td>self.fields['field1']</td><tr>\
<tr><td>Title 2:</td><td>self.fields['field2']</td><tr>\
<tr><td>Titles 3, 4, 5:</td><td>self.fields['field3']\
</td><td>self.fields['field4']</td><td>self.fields['field5']</td></tr>\
"
return html_string
But, after reading through the _html_output() and as_table() methods of Django's forms.py file, it doesn't look like it'll be that easy. If I write this from scratch, have to somehow account for errors, help text, etc. I think.
Is there an easy way to override something such that the form's HTML output can be defined like above? Or do I have to re-write things from scratch. If the latter, how can I account for all of the things I need to account for?
I wouldn't take this approach. You're better off creating the form in an HTML template that you include in the various templates where you have a form you want to display that way.
So create a my_strange_form.html template where you assume a 'form' object is passed in the context with the right number of fields. In that template just create the HTML, using things like {{ field.label_tag }} and {{ field }}. You can loop through the fields with a {% for field in form %} and check the counter of your loop with {{ forloop.counter }}. I foresee a lot of {% if forloop.counter... %} statements to generate the combined row, and it will look ugly, but you'll only have to look at it once :-)
Then in your main templates {% include 'my_strange_form.html' with form=form %}.

How to set a session variable in a HTML template in Django?

I'm trying to set value to Django session within the template and then posible used in the view.
I'm doing something like this
{% block body %}
<html>
{% request.session.fav_color="red" %}
<div> Is your favorite color {{ request.session.fav_color}} ?</div>
</html>
{% endblock %}
There are several reasons why this may not be a good idea:
Templates should deal with presentation only. If you are placing logic in the template it is supposed to be presentation logic. Placing business logic in the template is a violation of the SoC (separation of concerns).
Rendering the template often is one of the last things you do in a view so it is hard to get the cat back in the bag if you have already sent the data to the browser (and if you rendered the template but haven't sent data down the pipe you can just update the value in the view instead of trying to do it in the template).
If you are interacting with the user the traditional way to do it is using a form (even if it is a form with only the submit button) - or posting data to the server in the frontend using AJAX.

Template Contexts not recognized from external file (Django)

So, I've been editing a website and have many JavaScript functions that utilize the Contexts that the views.py file passes to the page. Until now, these functions have been contained in the base.html file and so have been loaded onto every page directly. However, to make things cleaner, I copy and pasted all the functions to an external .js file. Now, rather than use the contexts, the functions consider them to be literal strings.
Example:
$('#title').text('{{ event.name }}');
The above line will actually set the text of the element to say "{{ event.name }}" rather than the name of the event. Any ideas on how to fix this? I really don't want to keep these functions in the base file where they can be seen by anyone who inspects the page source.
It doesn't matter if you put your javascript functions in an external file or in your base.html it would still get exposed to the user. Only a minification of the file would actually help to trick the user from seeing the actual values but with javascript all your code is public.
Why you're having this problem is because when you rendered the javascript inline (in your base.html) you had access to the template context.
This is no longer the case and the Django template engine doesn't interpolate your {{ event.name }} anymore.
The problem you're facing as well is a good one. You should never mix and match javascript with Djangos template language or any template language for that matter and the only way of fixing it is to
a) start pulling the values from the DOM ie. render a proper DOM
b) to start to fetch the values from the server, traditionally using AJAX.
And the smallest example that I can muster at the moment is below:
Your view:
def my_django_view(request):
return HttpResponse(json.dumps({'meaningoflife':42}), mimetype='application/json')
Your HTML
<input type="hidden" id="myMeaning" value="{{ meaningoflife }}" />
Your javascript
var meaning = document.querySelector('#myMeaning').value;
alert(meaning); //should alert 42.
In your view you return some form of render_to_response which takes a template argument and a context argument. What the render_to_response function does is read your template, and replace all {{ placeholders }} with the values passed via the context dictionary.
Templates are essentially a complex version of this
"""
<h1>{{ person.name }}</h1>
<p>{{ person.phone_number }}</p>
""".format(person)
The problem is the templating engine does not know files specified by a scripts src attribute is actually a Django template. To fix this don't use the script src attribute. Instead do something like this.
<!--base.html-->
<h1>Site Title</h1>
<p>Some content</p>
<script>
{% include 'jsfile.js' %}
</script>
Using the include statement should do the trick.

Django HTML snippet for a model

I am new to Django and I am trying to find out how can I associate a HTML snippet with a model.
My HTML snippet is just a div. I want to reuse that div (you can think of it like a thumbnail)
Situation is like this: In my main page I want to show x objects and in my search page I want to show more objects. But the representation is the same.
I can write in the mainpage.html and searchpage.html the desired way of transforming the model object into a div but I am not sure what is the best way to reuse that transform?
I can add a function to my model which returns a HTML div, then I can call it from mainpage and searchpage templates. But that will couple the model and representation, which I believe is not a very nice thing to do.
If I am not mistaken inclusion_tags are the way to go but in which file should I keep the function definition?
As you rightly say, you don't want html in your models, it's goes against the MVC pattern.
Models are for storing data. Views are for selecting the data to present whilst Templates are used for the actual presentation of data. (See this note on django's interpretation of MVC).
To answer your question, you need a template (or even a template tag), to represent your model, say model_block.html. Something like
{% if obj %}
<div id=obj.id>
{{ obj.name }}
</div>
{% endif %}
Then include your template in your mainpage.html like
{% for obj in object_list %}
{% include 'model_block.html' %}
{% endfor %}
You can do the same thing in your searchpage.html, passing a different object_list variable from your view.

Can a django template be referenced from within a loop on another template?

I have a django template which loops over many notes/comments. As a simplified example take this.
{% for note in notes %}
<p>
Date added: {{ note.date_added }}
{{ note.note|urlize|url_target_blank|linebreaks }}
</p>
{% endfor %}
Then on the same page I have a form to add a new note. This note form is an ajax form and returns the newly submitted note back to the page and appends it at the end of the already existent note area.
I don't like this because I have to maintain the same html structure both in the page for the initial load, as well as in the response from the ajax form.
Is there a way to put a call to another template, inside of a template (in this for loop) so I can maintain the note formatting in one location only?
Thanks.
Perhaps you're looking for the "include" tag: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#include