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

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.

Related

Django templates Could not parse the remainder

I have this template, I am looping through all choices in a question, and I want to default check the question user previously selected. selected_choice variable is coming from my view and I got have it ok in my template.
{% extends 'base.html' %}
{% block content %}
<div id="detail" class="">
<form hx-post="{% url 'main:vote' question.id %}" hx-trigger="submit" hx-target="#detail" hx-swap="outerHTML">
{% csrf_token %}
<fieldset>
<legend><h1>{{ question.question_text }}</h1></legend>
{% if error_message %}<p>
<strong>{{ error_message }}</strong>
</p>
{% endif %}
{% for choice in question.choices.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" {% if selected_choice and choice.id==selected_choice %}checked{% endif %}>
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
</fieldset>
<button type="submit">Submit</button>
</form>
</div>
{% endblock content %}
I get this error
Could not parse the remainder: '==selected_choice' from 'choice.id==selected_choice'

Issue assigning form fields in the HTML template django

I have a model form and I wanted to know if it is possible to take a model form and assign the name of the specific field when it is running through a for loop within the template html file.
Here is what i have in the current html template:
{% extends "base.html" %}
{% block content %}
<h1>Add members to {{record.name}}</h1>
{% if message %}
<p>{{message}}</p>
{% endif %}
<form action="." method="POST">
{% csrf_token %}
{% for trans in transactions %}
{% if trans.record.id == record.id %}
{{ trans.user.username }}
{{ form.as_p }}
{% endif %}
{% endfor %}
<p>Tax: <input type="text" name="tax" value=""></p>
<p>Tip: <input type="text" name="tip" value=""></p>
<input type="submit" name="submit" value="submit">
</form>
{% endblock %}
here is the current form model:
class IndividualSplitTransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ['amount', 'description']
currently the format is looking like this:
omar
amount
description
hani
amount
description
assad
amount
description
tax
tip
so when i process it and i want to grab the amount assigned to each of the specific users and update a record. I want it to look something like this for easier processing in the view.
omar
omaramount
omardescription
hani
haniamount
hanidescription
assad
assadamount
assaddescription
tax
tip
so that when i am processing I can properly assign the corrent amount and description for each user when i am updating existing records with the amount.
is it possible to do that within the template itself or would i have to do it somewhere else.
UPDATED
So i tried to change my code and update it to get what i am trying to get but this is what i am getting...
Here is the html
{% extends "base.html" %}
{% block content %}
<h1>Add members to {{record.name}}</h1>
{% if message %}
<p>{{message}}</p>
{% endif %}
<form action="." method="POST">
{% csrf_token %}
{% for trans in transactions %}
{% if trans.record.id == record.id %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ trans.user.username }}{{ field.label }}{{ field|safe }}
</div>
{% endfor %}
{% endif %}
{% endfor %}
<p>Tax: <input type="text" name="tax" value=""></p>
<p>Tip: <input type="text" name="tip" value=""></p>
<input type="submit" name="submit" value="submit">
</form>
{% endblock %}
and here is what I am getting.
request returs
So if you look at the image, it is still just returning the last amount and description of the three that i entered... should i just create the whole form manually in the html file....
If you wanted the username + amount or username + description, then you to change away from form.as_p, because you will get the html <p><p/> tag for each field with label preceding it.
You want to dynamically add username then do by designing your own html content of the form manually.
There is a label_suffix, but prefix is not available. Even with suffix you should be doing it at the time of creating the form object.
Update:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ trans.user.username }} {{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}

Delete Button on "Delete Confirmation" Page of Django Admin Is not Working

Here is my template path
project/templates/app_name/delete_confirmation.html
{% extends "admin/base_site.html" %}
{% load i18n admin_urls %}
{% block content %}
{% if perms_lacking %}
<p>{% blocktrans with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}</p>
<ul>
{% for obj in perms_lacking %}
<li>{{ obj }}</li>
{% endfor %}
</ul>
{% elif protected %}
<p>{% blocktrans with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would require deleting the following protected related objects:{% endblocktrans %}</p>
<ul>
{% for obj in protected %}
<li>{{ obj }}</li>
{% endfor %}
</ul>
{% else %}
<p>{% blocktrans with escaped_object=object %}Are you sure you want to delete the {{ object_name }} "{{ escaped_object }}"? All of the following related items will be deleted:{% endblocktrans %}</p>
{% include "admin/includes/object_delete_summary.html" %}
<h2>{% trans "Objects" %}</h2>
<ul>{{ deleted_objects|unordered_list }}</ul>
<form action="" method="post">{% csrf_token %}
<div>
<input type="hidden" name="post" value="yes" />
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
<input type="submit" value="{% trans "Yes, I'm sure" %}" />
{% trans "No, take me back" %}
</div>
</form>
<input type="submit" value="{% trans "Cancel" %}" onclick="window.history.back(); return false;"/>
{% endif %}
{% endblock %}
I'm here trying to inherit django-admin's delete_confirmation.html template. I want to add a cancel button at the time of deleting the objects in an app. It shows me cancel button and it also works fine but delete button does nothing by doing so.
I've tried to add links in my "local template" which are defined in "admin template" but it raised error that "reverse url not found". Is there any workaround to do that? Please suggest me the right way to do it.
Thanks in Advance.
Instead of inheriting django-admin's delete-confirmation.html template copy the template from django/contrib/admin/templates/admin/delete_confirmation.html to your project directory and do the changes there itself.

django 1.6 - how do I insert a class-bassed view into a template as an {% include %}

My current template structure has a home.html that extends from a base.html. That home.html file also has its own {% include %} tags that pull in from other templates (contact forms, etc).
The problem I am having is that when I use the {% include %} tag on a class based view, nothing gets rendered in my template. I can still go to the url of the class based view and it renders just fine there.
In this case frontpabe/contact.html is a typical function based view, while frontpage/skills_list.html is a class based view.
home.html:
<div class="col-lg-4">
{% block contact %}
{% include 'frontpage/contact.html' %}
{% endblock %}
{% block skills %}
{% include 'frontpage/skills_list.html' %}
{% endblock %}
</div>
contact.html:
{% block contact %}
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<input type="text" name="subject" placeholder="I want a free estimate...">
<p></p>
<input type="text" name="email" placeholder="email address (optional)">
<p></p>
<textarea name="message" placeholder="here are some things I need..."></textarea>
<br />
<input type="submit" value="Submit">
</form>
{% endblock %}
skills_list.html:
{% block skills %}
{% for item in skills_list %}
<h3 style='background-color:yellow;'> {{ item.skills }} </h3>
{% endfor %}
{% endblock %}
Your problem won't have anything to do with whether it's a function-based view or a class-based view--the {% include %} tag merely includes the template itself--it doesn't call the view. It's literally as if you just copied + pasted the text of the contact or skills templates into your front page template.
Without seeing the rest of your code, I can't be 100% sure, but a likely place for your problem is that the view class or function for your homepage doesn't have a variable skills_list or, if it does, that it is empty. So your skills_list.html template is being used, it's just rendering the results of looping over an empty list (a quick check would be to add a tiny bit of static text, like "HELLO?" to skills_list.html outside of your {% for ... %}; if you see that, you're definitely rendering the template.
If it is a missing skills_list variable, it's almost certainly because of the misunderstanding about views/templates. You're probably defining that template in the CBV associates with skills_list.html template--but, again, the {% include %} tag doesn't call your view; it just includes the raw template itself.
Extends and include are different and should not be used together. If you are going to define blocks then have the children template extend the parent and override the blocks- no includes necessary:
home.html:
<div class="col-lg-4">
{% block contact %}
{% endblock %}
{% block skills %}
{% endblock %}
</div>
contact.html:
{% extends 'home.html' %}
{% block contact %}
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<input type="text" name="subject" placeholder="I want a free estimate...">
<p></p>
<input type="text" name="email" placeholder="email address (optional)">
<p></p>
<textarea name="message" placeholder="here are some things I need..."></textarea>
<br />
<input type="submit" value="Submit">
</form>
{% endblock %}
skills_list.html:
{% extends 'home.html' %}
{% block skills %}
{% for item in skills_list %}
<h3 style='background-color:yellow;'> {{ item.skills }} </h3>
{% endfor %}
{% endblock %}
Alternatively, you could use includes:
home.html:
<div class="col-lg-4">
{% include 'frontpage/contact.html' %}
{% include 'frontpage/skills_list.html' %}
</div>
contact.html:
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<input type="text" name="subject" placeholder="I want a free estimate...">
<p></p>
<input type="text" name="email" placeholder="email address (optional)">
<p></p>
<textarea name="message" placeholder="here are some things I need..."></textarea>
<br />
<input type="submit" value="Submit">
</form>
skills_list.html:
{% for item in skills_list %}
<h3 style='background-color:yellow;'> {{ item.skills }} </h3>
{% endfor %}

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.