Django template - inline POST as hyperlink logic - django

I have a simple yet frustrating problem:
in my template I have:
{% for lang in LANGUAGES %}
{% if lang.0 != LANGUAGE_CODE %}
<input type="hidden" name="language" value="{{ lang.0 }}">
{{ lang.1 }} |
{% else %}
{{ lang.1 }}
{% endif %}
{% endfor %}
The language switching works fine, it's just that the pipe separator which I want to separate the two languages which can be selected doesn't stay in the middle. Obviously when the first statement is evaluated to false in the first instance then the linked option is written last and the pipe appears at the end. Does anyone have a simple way to get a pipe separator fixed in between the two on both conditions?

maybe try using the forloop counter...? ...not to write the separator in the last item
{% for lang in LANGUAGES %}
{% if lang.0 != LANGUAGE_CODE %}
<input type="hidden" name="language" value="{{ lang.0 }}">
{{ lang.1 }}
{% else %}
{{ lang.1 }}
{% endif %}
{% if forloop.last != true %}
|
{% endif %}
{% endfor %}

Related

Django templates - how to strictly check for equality of a string

I struggling to solve the following:
I am customizing django tabular inline template which contains several fields.
I have a condition
{% if field.field.name == 'productid' %} ... {% endif %}
However there are two fields that have the ... condition applied which is "productid" and "distributionid price productid" - both contain the productid word. However, I want only the former to have it. How can I make this condition more strict?
Any help will be much appreciated.
EDIT:
html file:
{% if field.field.name == 'productid' %}
<input type="text" name="PN" id="PN" placeholder="PN:"/>
{% endif %}
{% if field.field.name != 'productid' %}
<td class="field-{{ field.field.name }}"
data-id="{{ field.field.id }}" data-type="id">
{% if field.is_readonly %}
<p>{{ field.contents }}</p>
{% else %}
{{ field.field.errors.as_ul }}
{{ field.field }}
{% endif %}
(rerults in )
Your if condition is outside the field td.
Just put it with field.field tag
{% if field.is_readonly or not field.field.is_hidden %}
<td{% if field.field.name %} class="field-{{ field.field.name }}"{% endif %}>
{% if field.is_readonly %}
<p>{{ field.contents }}</p>
{% else %}
{{ field.field.errors.as_ul }}
{{ field.field }}
{% if field.field.name == 'productid' %}
<input type="text" name="PN" id="PN" placeholder="PN:"/>
{% endif %}
{% endif %}
</td>
{% endif %}

Equivalent of using if .. else as an expression in the Django Template Language

In Python, there are two ways to use if and else: either for Boolean flow control, in which case it is used with colons and indentation, or as an expression on a single line as described in https://www.pythoncentral.io/one-line-if-statement-in-python-ternary-conditional-operator/.
As far as I can tell, the Django Template Language's {% if %} ... {% else %} ... {% endif %} tags are equivalent to the former. However, I was wondering if I could somehow implement the latter to refactor the code below:
<form action="" method="post">{% csrf_token %}
{% for field in form %}
{% if field.name == "checkin_type" %}
<div class="auto-submit">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</div>
{% else %}
<div>
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</div>
{% endif %}
{% endfor %}
<input type="submit" value="Send message" />
</form>
Here I am looping over the fields of the form and adding a particular class, "auto-submit", to the enclosing <div> element of a particular field ("checkin_type"). I'd like to refactor this along the lines of the following 'pseudocode':
<form action="" method="post">{% csrf_token %}
{% for field in form %}
<div class="{% if field.name=='checkin_type'%}auto-submit{% else %}{% endif %}">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
<input type="submit" value="Send message" />
</form>
In other words, I'd like to reduce code repetition by using if...else statements in the definition of the class only, by using a kind of ternary operator. Is this possible in the DTL?
By the way, if I try to load the template with the code above I get a TemplateSyntaxError:
Could not parse the remainder: '=='checkin_type'' from 'field.name=='checkin_type''
Perhaps I just need to do the quote escaping correctly?
It should be spaces before and after == and you don't need empty {% else %} block:
<div class="{% if field.name == 'checkin_type'%}auto-submit{% endif %}">
Django has a built-in tag filter yesno
You can use it like so:
<div class="{{ field.name|yesno:"checkin_type,''" }}">
https://docs.djangoproject.com/en/4.0/ref/templates/builtins/#yesno

Capture the results of multiple radiobox selection Django

Total newb here...
I'm making a poll where I display 5 questions on a page. Each question has 4 radioboxes.
In my django template, I'm looping through a container (latest_poll_list) of all my questions (poll):
<form action="/first/vote/" method="post">
{% csrf_token %}
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% for choice in poll.choice_set.all %}
<input type="radio" name="choice{{poll.id}}" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
{% endfor %}
{% endfor %}
<input type="submit" value="Vote" />
</form>
Lastly how do I return results from multiple questions? Do I have to put the choice+poll.id into an array/container?
Also, how does django know that forloop.counter refers to the inner loop and not the outer loop?
Thanks for your patience while I ramp up!
I would consider using a formset or a model formset.
and the forloop.counter is for the inner most forloop, however you can pass the counter from an outer forloop into the inner forloop using the {% with %} tag:
{% for object in objects %}
<label>{{ forloop.counter }}</label>
{% with outside_counter=forloop.counter %}
{% for subobject in object %}
<p>outside: {{ outside_counter }} inside: {{ forloop.counter }}</p>
{% endfor %}
{% endwith %}
{% endfor %}
results:
<label>0</label>
<p>outside: 0 inside: 0</p>
<p>outside: 0 inside: 1</p>
<label>1</label>
<p>outside: 1 inside: 0</p>
<p>outside: 1 inside: 1</p>
...

Django: Redirect after posting a comment

I am trying to redirect the user back to the page where the comment was posted. I found this post on Django's site but I am doing something wrong because it won't redirect back.
Where should the input be placed to have it properly redirected?
{% load comments i18n %}
<form action="{% comment_form_target %}" method="post">{% csrf_token %}
{% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field.errors %}{{ field.errors }}{% endif %}
<input type="hidden" name="next" value="{% url proposal proposal.id %}" />
<p
{% if field.errors %} class="error"{% endif %}
{% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}
{% ifequal field.name "name" %} style="display:none;"{% endifequal %}
{% ifequal field.name "email" %} style="display:none;"{% endifequal %}
{% ifequal field.name "url" %} style="display:none;"{% endifequal %}
{% ifequal field.name "title" %} style="display:none;"{% endifequal %}>
<!-- {{ field.label_tag }} -->{{ field }}
</p>
{% endif %}
{% endfor %}
<p class="submit">
<!-- <button><input type="submit" name="post" value="{% trans "Send" %}" /></button> -->
<button type="submit">Send</button>
<!-- <input type="submit" name="preview" class="submit-preview" value="{% trans "Preview" %}" /> -->
</p>
</form>
Maybe you don't need to check for next variable in your template. You could try changing:
{% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
to just:
<input type="hidden" name="next" value="/added/comment/page/" />
In case you use views.py, redirecting from there seems more obvious, at least for me, as it helps keep the concern away from the template:
from django.http import HttpResponseRedirect
HttpResponseRedirect("/path/to/redirect")
The problem with axel22's answer is that it requires a change to each template that requires the comment form - if you have multiple object types that can be commented on, this is not DRY.
Unfortunately, I'm also still looking for an answer that works.
if you are using {% render_comment_form for object %} tag in your template, just add something like {% url object's_named_view object.id as next %} or wrap it with {% with object.get_absolute_url as next %} ... {% endwith %} construction.
See my solution here: Django: Redirect to current article after comment post
It basically uses a view that's triggered by the comment post url which redirects back to the original referrer page.

Django: How to define "Next" within the Comments form

I am using the Django comments framework in two places on my site. After each submission, I'd like for the user to just be redirected back to the original page they were on.
How do you define the "next" variable so the user is redirected?
Information on the redirect : http://docs.djangoproject.com/en/dev/ref/contrib/comments/#redirecting-after-the-comment-post
Also, here is the form I am using. The comment.types do not work, but that is what I think I am supposed to do - define two different next inputs for each comment type (picture vs meal).
{% load comments i18n %}
<form action="{% comment_form_target %}" method="post">{% csrf_token %}
{% if comment.type == '19' %}
<input type="hidden" name="next" value="{% url meal comment.object_pk %}" />
{% endif %}
{% if comment.type == '23' %}
<input type="hidden" name="next" value="{% url picture comment.object_pk %}" />
{% endif %}
<!-- <input type="hidden" name="next" value="{{ next }}" /> -->
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field.errors %}{{ field.errors }}{% endif %}
<p
{% if field.errors %} class="error"{% endif %}
{% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}
{% ifequal field.name "name" %} style="display:none;"{% endifequal %}
{% ifequal field.name "email" %} style="display:none;"{% endifequal %}
{% ifequal field.name "url" %} style="display:none;"{% endifequal %}
{% ifequal field.name "title" %} style="display:none;"{% endifequal %}>
<!-- {{ field.label_tag }} -->{{ field }}
</p>
{% endif %}
{% endfor %}
<p class="submit">
<button type="submit">Send</button>
<!-- <input type="submit" name="preview" class="submit-preview" value="{% trans "Preview" %}" /> -->
</p>
</form>
And then on the Meal & Picture pages I have:
<h4>Post a Message</h4>
{% render_comment_form for meal %}
<h4>Post a Message</h4>
{% render_comment_form for picture %}
Figured it out. To use the next with multiple objects, use an if statement.
{% if picture %}
<input type="hidden" name="next" value="{% url picture picture.id %}" />
{% endif %}
If you want to stay on the same page ajax is an option, you could use something like django_ajaxcomments, there are quite a few posts on others ways to do this with ajax.