I'm trying allauth for the first time and having difficulty signing up for the first time. I am using the Facebook support and I connect to Facebook successfully, logging in and get to /accounts/social/signup:
where my Facebook name and email address are pre-filled, but the button doesn't work, quite possibly because the form action is empty. I checked the allauth package template, and it seems designed this way. I'm not sure what's going on, but it's not working for me. Please help!
Excerpt from rendered page http://localhost:8000/accounts/social/signup/
<p>{% blocktrans with provider_name=account.get_provider.name site_name=site.name %}You are
about to use your {{provider_name}} account to login to
{{site_name}}. As a final step, please complete the following form:{% endblocktrans %}</p>
<form class="signup" id="signup_form" method="post" action="">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<button type="submit">{% trans "Sign Up" %} »</button>
</form>
excerpt from /virtualenvs/myproject/lib/python2.7/site-packages/allauth/templates/socialaccount/signup.html
<form class="signup" id="signup_form" method="post" action="">
{% csrf_token %}
{{ form.as_p }}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<button type="submit">{% trans "Sign Up" %} »</button>
</form>
Action was left out in code and has now been changed on github, although apparently not in the pip package directory, thus I installed the error.
Related
There is a view in the Django project (a paginated blog) that is responsible for how likes work. It has one drawback: when a user likes a post, it is redirected to the main page of the site. How can I fix this so that the user would remain on the page where they liked.
views.py
class AddLikeView(View):
def post(self, request, *args, **kwargs):
blog_post_id = int(request.POST.get('blog_post_id'))
user_id = int(request.POST.get('user_id'))
url_from = request.POST.get('url_from')
user_inst = User.objects.get(id=user_id)
blog_post_inst = News.objects.get(id=blog_post_id)
try:
blog_like_inst = BlogLikes.objects.get(blog_post=blog_post_inst, liked_by=user_inst)
except Exception as e:
blog_like = BlogLikes(blog_post=blog_post_inst,
liked_by=user_inst,
like=True)
blog_like.save()
return redirect(url_from)
template.py
<form action="{% if not is_liked_bool %}{% url 'add' %}{% else %}{% url 'remove' %}{% endif %}" method="post">
{% csrf_token %}
<input type="hidden" name="blog_post_id" value="{{ blog_post_id }}">
<input type="hidden" name="user_id" value="{% if user.is_authenticated %}{{ request.user.id }}{% else %}None{% endif %}">
<input type="hidden" name="url_from" value="{{ request.path }}">
{% if is_liked_bool %}
<input type="hidden" name="blog_likes_id" value="{{ blog_likes_id }}">
{% endif %}
<button type="submit" class="btn btn-success">
{% if not is_liked_bool %}
<i class="fi-xnluxl-heart">♥</i>
{% else %}
<i class="fi-xnluxl-heart-solid">♥</i>
{% endif %}
<span class="likes-qty">{{ likes_counter }}</span>
</button>
I think you should check the url_from field first. Just print it and if it's wrong, you should change the {{request.path}} field in your template.
You can try this:
{{ request.get_full_path }}
And also if I remember correctly, you can access the path with request.path in your view and no need to send path via template.
How can I add attribute autocomplete="off" to the input login template form for an admin?
I'm find this in the login.html template but can't find where is the form template
<div class="form-row">
{{ form.username.errors }}
{{ form.username.label_tag }} {{ form.username }}
</div>
If you need to change behavior based on whether or not the user is admin/staff:
{% if request.user.is_staff %}
<form autocomplete="off" method="post" action="action_name">
<input autocomplete="off" name="hidden" type="text" style="display:none;">
{% else %}
<form method="post" action="action_name">
{% endif %}
<div class="form-row">
And complete the rest of the form as you would.
Reference for the form and input tags to turn autocomplete off (note autocomplete is "off" in the input tag as per testing in comments):
https://gist.github.com/niksumeiko/360164708c3b326bd1c8
I'm trying to create custom template for Django's build-in login view. At the moment it looks like (registration/login.html):
<form method="post">
{% csrf_token %}
{% for field in form %}
{% include 'registration/form_field.html' %}
{% endfor %}
<input class="btn btn-primary btn-block" type="submit" value="{% trans "Log in" %}">
</form>
And registration/form_field.html file is:
<div class="form-group {% if field.errors %}has-error{% endif %}">
<input class="form-control" name="{{ field.name }}" placeholder="{{ field.label }}" {% if field.data %}value="{{ field.data }}"{% endif %} />
{% if field.errors %}
<span class='text-danger'>{{ field.errors|join:'<br>' }}</span>
{% endif %}
</div>
Everything works as expected, only problem is that password is shown in clear text.
To solve this type="password" should be set for password field (and type="text" for username field).
Is it possible to implement this using field variable (i.e. something like {{ field.type }})?
You can implement a PasswordInput widget in your form definition, that will render as a password field with type="password".
class ExampleForm(forms.Form):
password = forms.CharField(label='Password',
widget=forms.PasswordInput())
In the templates,
{{form.password}}
will render this field, which is the cleanest solution.
You may also access the type of the field (as you wanted), like this:
{{form.fields.password.widget.input_type}}
Note that if you'd like further customization beyond simply rendering the form, there's nothing wrong with just writing your own html for the fields.
I'm trying to implement login/registration views in Flask that support both regular login (through Flask-Security) and OAuth login (through Flask-Social).
My website uses CSRF protection, but when I implement a link to the OAuth login page (as per the Flask-Social example project) I get a CSRF error. Here is the template:
{% extends "base.html" %}
{% from "security/_macros.html" import render_field_with_errors, render_field %}
{% block title %}Login{% endblock %}
{% block body %}
<h1>Login</h1>
{% include "security/_messages.html" %}
<form action="{{ url_for_security('login') }}" method="POST"
name="login_user_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email,
class="form-control", placeholder="Your email") }}
{{ render_field_with_errors(login_user_form.password,
class="form-control", placeholder="Password") }}
{{ render_field(login_user_form.remember) }}
{{ render_field(login_user_form.next) }}
{{ render_field(login_user_form.submit, class="btn btn-primary") }}
</form>
<form action="{{ url_for('social.login', provider_id='google') }}"
name='google_login_form' method="POST">
<input class="btn btn-primary btn-large" type="submit"
name="login_google" value="Login with Google" >
</form>
{% include "security/_menu.html" %}
{% endblock %}
The problem seems to be that the second form does not have a CSRF field; what can I do about this?
You should follow the Flask-WTF docs on using templates without forms.
As per the docs, in the app
from flask_wtf.csrf import CsrfProtect
CsrfProtect(app)
and in the template
<form method="post" action="/">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>
Your second form would be
<form action="{{ url_for('social.login', provider_id='google') }}"
name='google_login_form' method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input class="btn btn-primary btn-large" type="submit"
name="login_google" value="Login with Google" >
</form>
how can I get rid of users being directed to the “Thanks you
for your comment” page after commenting in Django site? I want users to be
redirected to the same page they commented. I’m using Django
comments.
I’ve tried adding:
<input type=”hidden” name=”next” value=”"{% url
django.contrib.comments.views.comments.comment_done %}" />
But it’s not working. Below is codes in my comment/form.html
{% load comments %}
{% get_comment_count for sol as comment_count %}
{% get_comment_list for sol as comment_list %}
{% get_comment_form for sol as form %}
{% if user.is_authenticated %}
<form action="{% comment_form_target %}" method="post">
{% csrf_token %}
{% if next %}<input type="hidden" name="next" value="{% url
django.contrib.comments.views.comments.comment_done %}" />{% endif %}
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field.name != "name" and field.name != "email"
and field.name != "url" %}
{% if field.errors %}{{ field.errors }}{% endif %}
{{ field }}
{% endif %}
{% endif %}
{% endfor %}
<input class="submit-post" name="post" type="submit" value="Comment" />
</form>
{% else %}
I'm sorry, but you must be <a href="javascript:alert('send to
login page')">logged in</a> to submit comments.
{% endif %}
First let's review your code:
<input type=”hidden” name=”next” value=”"{% url
django.contrib.comments.views.comments.comment_done %}" />
Two double quotes: value=”"{% url
The url is comment_done: so this will redirect to the "Thank you for your comment page", which you want to avoid
Use url names instead of module name: {% url comments-comment-done %} rather than {% url django.contrib.comments.views.comments.comment_done %}
Instead, you can redirect the comment poster to the absolute url of the object he commented:
<input type="hidden" name="next" value="{{ form.instance.content_object.get_absolute_url }}" />
This assume that your model has the standard get_absolute_url() method defined.
Or even, you can redirect the user to the very same page he's on:
<input type="hidden" name="next" value="{{ request.path }}" />
Or the previous page he visited:
<input type="hidden" name="next" value="{{ request.META.HTTP_REFERER }}" />