How do I customize Django's comments form? - django

I am trying to customize Django's comments form. Inside django.contrib.comments.forms I noticed that all the field forms are declared in the class CommentDetailForm, which is inherited from CommentSecurityForm. Then I think when I write the template tag {% get_comment_form for order as form %}, it's getting the class called CommentForm which inherits CommentDetailForm with a honeypot field.
I wanted to customize the comments form so that it only displays the comments field (and not the optional name, email, or URL fields). Those information will be given by the current logged in user. In fact, only logged in users with certain UserProfile.user_type (UserProfile has a foreign key to User) are allow to comment.
Any tips on how to achieve this? Looking at the source code of the Django's comments already scares me lol.
EDIT:
Here is how the comment template looks so far:
{% get_comment_form for order as form %}
<form action = "{% comment_form_target %}" method = "post">
{% csrf_token %}
{{ form }}
<input type = "submit" name = "submit" value = "Post">
</form>
And the site looks like this
I want to hide Name, Email address, and URL.

You should be able to do all of this in the template:
{% ifequal User.profile.user_type "comment_type" %}
{% get_comment_form for order as form %}
<form action="{% comment_form_target %}" method="post">
{% csrf_token %}
{% for field in form %}
{% ifequal field.name "name" %}
<input id="id_name" type="hidden" name="name" value="{{ user.username }}" />
{% else %}{% ifequal field.name "email" %}
<input type="hidden" name="email" value="{{ user.email }}" id="id_email" />
{% else %}{{ field }}{% endifequal %}{% endifequal %}
{% endfor %}
<input type="submit" name="submit" value="Post">
</form>
{% endifequal %}

Related

Placement of {% if form.errors %} on login template

I'm not sure if I'm allowed to ask these types of questions here since it's not a problem per say, so please let me know. But I was wondering for the login.html template on Django:
{% extends 'learning_logs/base.html' %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method = "post" action="{% url 'login' %}">
{% csrf_token %}
{{ form.as_p }}
<button name = "submit">log in</button>
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>
{% endblock content %}
How come it checks for the form.errors before the it even processes the form? Thanks for any help on this question.
The template ordering doesn't define how the form logic works, only how certain items are displayed. You could put the {% if form.errors %} block after the <form> and there would be no difference to how the form is processed by Django. Furthermore, form.errors will only exist once a form has been validated with is_valid() and any errors exist.

Customized django all-auth form not submitting

I am using the django all-auth login form. I wanted to customize the look of the form fields so I changed login.html within the account folder to look like this:
<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
{% for field in form.visible_fields|slice:'2' %}
<div class="row form-group">
{% if field.name == 'login' %}
<input type="text" placeholder="Email"><i class="fas fa-at"></i>
{% else %}
<input type="password" placeholder="Password"><i class="la la-lock"></i>
{% endif %}
</div>
{% endfor %}
Forgot Password?
<button type="submit">Sign In</button>
</form>
The form renders exactly how I would like it to, however nothing happens when I click on submit. What is strange to me is that the form submits perfectly fine if in place of my for loop I simply type {{ form.as_p }}, it just doesn't look how I want. Can anyone see an error in my loop, or is there something else wrong here. I have been looking for a solution online but so far been unsuccessful
You need to specify the names of the fields in your input tags otherwise the POST dictionary will be empty. You are using {% if field.name == 'login' %} but you forgot to specify the name attribute. Same applies for the password input.
<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
{% for field in form.visible_fields|slice:'2' %}
<div class="row form-group">
{% if field.name == 'login' %}
<input name='login' type="text" placeholder="Email"><i class="fas fa-at"></i>
{% else %}
<input name='password' type="password" placeholder="Password"><i class="la la-lock"></i>
{% endif %}
</div>
{% endfor %}
Forgot Password?
<button type="submit">Sign In</button>
</form>

Change login label in Django auth form

I'm trying to change the login username label but without any success. Here is the website:
What I'd like to do is print "Usuário and e-mail" instead of just "Usuário" label:
I didn't customize the login form, in this way, I'm using all standard auth process.
#template
<form action="{% url 'login' %}" method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}" />
<p><input type="submit" value="Login"></p>
</form>
If you guys have any suggestion modifying the input field through CSS style, it's welcome as well!
Thanks!
EDIT:
{% for field in form %}
<div class="fieldWrapper">
{% if field.label_tag == 'Usuário' %}
{% field.label_tag = 'Usuário ou e-mail:' %}
{% elif %}
{{ field.label_tag }}
{% endif %}
{{ field.label_tag }}{{ field }}
</div>
{% endfor %}
Value the label in the attribute form.

how to save user's inputs without backeneds

I am just learning Django and web development in general and I was wondering if what I want to do is possible. I would like to write a Django quiz that saves the answers a user inputs without needing a backend. Is this possible?If it is not possible what is the simplest and easiest way I can do this. My template:
{% extends "base.html" %}
{% block title %}Exam Questions{% endblock %}
{% block content %}
{% if all_questions %}
<form action="{% url 'save_answer' %}" method="post">
{% csrf_token %}
{% for question in all_questions %}
<h3>{{question.text }}</h3>
<input type="hidden" name="exam_id" value="{{ question.exam.id }}">
<input type="hidden" name="question_id" value="{{ question.id }}">
<input type="hidden" value="{{question.answer_set.all}}" name="answers">
{% for answer in question.answer_set.all %}
<p><input type="radio" name="answer" value="{{ answer.id }}">{{ answer.text }}</p>
{% endfor %}
{% endfor %}
<input type="submit" value="Send">
</form>
{% else %}
<h2>No questions available</h2>
{% endif %}
{% endblock %}
Now I would like to know how to save user answers without backends
Afaik, you can save it in your backend (django forms doc), or save it with javascript in a client browser cookie.
First, make a litle change with your template to make radio choices work
<p><input type="radio" name="answer_{{ question.id }}" value="{{ answer.id }}">{{ answer.option }}</p>
Then, here is the code to store answers to session:
def post(self, request, *args, **kwargs):
post = request.POST
question_ids = post.getlist('question_id')
results = dict()
for id in question_ids:
answer = post.get('answer_%s' % id)
results[id] = answer
# Save to session or do whatever you want.
request.session['results'] = results
# Response to review
return JsonResponse(results)

Custom template for Django's comments application does not display fields

I want to use django.contrib.comments in a blogging application and customize the way the form is displayed. My problem is that I can't get the fields to display although displaying the hidden fields works just fine. I had a look at the docs and compared it with the regular way of displaying forms but honestly I don't know why the following doesn't work out:
{% get_comment_form for comments_object as form %}
<form action="{% comment_form_target %}" method="POST">
[…]
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.fields %}
{{field}}
{% endfor %}
[…]
</form>
The output looks like this:
<form action="/comments/post/" method="POST">
<input type="hidden" name="content_type" value="flatpages.flatpage" id="id_content_type" />
<input type="hidden" name="object_pk" value="1" id="id_object_pk" />
<input type="hidden" name="timestamp" value="1269522506" id="id_timestamp" />
<input type="hidden" name="security_hash" value="ec4…0fd" id="id_security_hash" />
content_type
object_pk
timestamp
security_hash
name
email
url
comment
honeypot
[…]
</form>
</div>
Can you tell me what I'm doing wrong? Thanks in advance
use {% for field in form.visible_fields %}
form.fields is a dictionary where the keys are the names of the fields, and the values are the actual form.Field() objects.
You can also do {% for field in form %} which should include both hidden and visible fields.