Django Firebase check if user is logged in - django

I'm trying to check if the user is logged into firebase in Django by requesting the session_uid in the home.html file. Which seems not to be working. How can I check if the firebase user is logged in?
def login(request):
if request.method == 'POST':
form = UserLoginForm(request.POST)
if form.is_valid():
# form.save()
email = form.cleaned_data.get('email')
password = form.cleaned_data.get('password')
user = auth.sign_in_with_email_and_password(email, password)
session_id = user['idToken']
request.session['uid'] = str(session_id)
messages.success(request, f'Account created for {email}!')
return redirect(request, 'blog-home')
else:
form = UserLoginForm()
return render(request, 'users/login.html', {'form': form, 'title': 'Login'})
home.html
{% extends "home/base.html" %} -->
{% block content %}
{% if request.session.session_id %}
{% for post in posts %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="#">{{ post.author }}</a>
<small class="text-muted">{{ post.date_posted }}</small>
</div>
<h2><a class="article-title" href="#">{{ post.title }}</a></h2>
<p class="article-content">{{ post.content }}</p>
</div>
</article>
{% endfor %}
{% else %}
<h2>You need to login</h2>
{% endif %}
{% endblock content %}

You do the following in the view
session_id = user['idToken']
request.session['uid'] = str(session_id)
yet access like request.session.session_id in the template. You should be doing request.session.uid.

Related

Django: User Login only working with terminal created users

I'm only new to django & this is my first time posting on stack overflow so appologies if I havent done this right.
My problem is that when I use my login function, it only seems to work with those created with the createsuperuser command in the terminal. Those created within the website just dont work.
The users show within the admin panel and have a password within them.
models.py
class Trickster_User(AbstractBaseUser, PermissionsMixin):
UserID = models.AutoField(primary_key=True)
Email = models.EmailField(('Email Address'), unique=True)
Username = models.CharField(('Username'),max_length=25, unique=True)
FirstName = models.CharField(('First Name'),max_length=25)
LastName = models.CharField(('Last Name'),max_length=25)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
objects = CustomUserManager()
USERNAME_FIELD = 'Email'
REQUIRED_FIELDS = ['Username', 'FirstName', 'LastName']
def __str__(self):
return self.FirstName + ' ' + self.LastName
views.py
def user_login(request):
context = {}
user = request.user
if user.is_authenticated:
return redirect('home')
if request.method == "POST":
form = UserAuthenticationForm(request.POST)
if form.is_valid():
Email = request.POST['Email']
password = request.POST['password']
user = authenticate(Email=Email, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
form = UserAuthenticationForm()
context['user_login'] = form
return render(request, 'authentication/login.html', context)
forms.py
class UserAuthenticationForm(forms.ModelForm):
Email = forms.EmailField(widget=forms.EmailInput(attrs={'class':'form-control'}))
password = forms.CharField(label='password', widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = Trickster_User
fields = ('Email', 'password')
def clean(self):
Email = self.cleaned_data['Email']
password = self.cleaned_data['password']
if not authenticate(Email=Email, password=password):
raise forms.ValidationError("Invalid Login")
login.html
{% block content %}
<div class="shadow p-4 mb-5 bg-body rounded">
<h1> Login </h1>
<br/><br/>
<form action="" method=POST enctype="multipart/form-data">
{% csrf_token %}
{% for feild in user_login %}
<p>
{{ feild.label_tag }}
{{ feild}}
{% if feild.help_text %}
<small style="color: grey">{{ feild.help_text }}</small>
{% endif %}
{% for errors in field.errors %}
<p style="color: red">{{ feild.errors }}</p>
{% endfor %}
{% if user_login.non_feild_errors %}
<div style="color:red";>
<p>{{ user_login.non_feild_errors }}</p>
</div>
{% endif %}
</p>
{% endfor %}
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
{% endblock %}
Code to register users:
views.py
def register_user(request):
context = {}
if request.method == "POST":
form = UserRegistrationForm(request.POST)
if form.is_valid():
form.save()
Email = form.cleaned_data.get('Email')
raw_password = form.cleaned_data.get('password1')
user = authenticate(Email=Email, password=raw_password)
login(request, user)
messages.success(request, ("Registration Successful! Password"))
return redirect('home')
else:
context['UserRegistrationForm'] = form
else:
form = UserRegistrationForm()
context['UserRegistrationForm'] = form
return render(request, 'authentication/register_user.html', context)
register_user.html
{% block content %}
{% if form.errors %}
<div class="alert alert-warning alert-dismissible fade show" role="alert">
There was an error with your form!
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endif %}
<div class="shadow p-4 mb-5 bg-body rounded">
<h1> Register </h1>
<br/><br/>
<form action="{% url 'register_user' %}" method=POST enctype="multipart/form-data">
{% csrf_token %}
{% for feild in UserRegistrationForm %}
<p>
{{ feild.label_tag }}
{{ feild}}
{% if feild.help_text %}
<small style="color: grey">{{ feild.help_text }}</small>
{% endif %}
{% for errors in field.errors %}
<p style="color: red">{{ feild.errors }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
{% endblock %}
Ive seen one other post on something simmilar to this but the only solution posted was to change the 'is_active' status to True by default.
I tried this and am still running into same issue.

how to display a form in function based view

I have got an error when I tried to display a form in function-based view in Django. I could display it in another HTML file and users can make their comments to the blog. But, I think it can be more convenient for users if they can make a comment on the same blog-detail HTML file, so I wanna implement it.
When I tried, this error showed up. "NoReverseMatch at /blogs/blog/30/
Reverse for 'blog' with no arguments not found. 1 pattern(s) tried: ['blogs/blog/(?P[0-9]+)/$']"
Any comments can help me and thanks for your time in advance!!
Here are the codes I wrote...
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('user', 'text',)
#views.py
#login_required
def blog(request, pk):
blog = get_object_or_404(Blog, pk=pk)
form = CommentForm()
# if request.method == 'POST':
# form = CommentForm(request.POST)
# if form.is_valid():
# comment = form.save(commit=False)
# comment.blog = blog
# comment.save()
# return redirect('blog', pk=blog.pk)
# else:
# form = CommentForm()
if blog.link_1 is not None and blog.link_2 is not None:
link_1 = blog.link_1
link_2 = blog.link_2
context = {
'blog': blog,
'link_1': link_1,
'link_2': link_2,
'form': form,
}
elif blog.link_1 is not None or blog.link_2 is not None:
link_1 = blog.link_1
link_2 = blog.link_2
context = {
'blog': blog,
'link_1': link_1,
'link_2': link_2,
'form': form,
}
else:
context = {
'blog': blog,
'form': form,
}
return render(request, 'blog/blog.html', context)
#login_required
def add_comment(request, pk):
blog = get_object_or_404(Blog, pk=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.blog = blog
comment.save()
return redirect('blog', pk=blog.pk)
else:
form = CommentForm()
context = {
'form': form,
}
return render(request, 'blog/blog.html', context)
#urls.py
path('blog/<int:pk>/', views.blog, name='blog'),
path('blog/<int:pk>/comment/', views.add_comment, name='add_comment'),
#blog.html
{% extends 'base.html' %}
{% block title %}|{{ blog.title }}{% endblock %}
{% block content %}
<div class="header-bar">
← 戻る
</div>
<div class="body-container">
<div class="created-edit-delete">
<p>
{% if request.user == blog.user %}
あなたが{{ blog.created }}に作成</p>
{% else %}
{{ blog.user }}が{{ blog.created }}に作成</p>
{% endif %}
<div class="icons">
{% if request.user == blog.user %}
{% endif %}
</div>
</div>
<h1>{{ blog.title }}</h1>
<p class="blog-content">{{ blog.content_1 }}</p>
{% if blog.content_2 %}
<p class="blog-content">{{ blog.content_2 }}</p>
{% endif %}
{% if blog.content_2 %}
<p class="blog-content">{{ blog.content_3 }}</p>
{% endif %}
<div class="ref-links">
{% if link_1 %}
参考リンク
{% endif %}
{% if link_2 %}
参考リンク
{% endif %}
</div>
<hr>
<div class="comment-area">
<div class="comment-form">
<h2>New comment</h2>
<form action="{% url 'add_comment' blog.id %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="button">追加</button>
</form>
</div>
<div class="comment-all">
{% for comment in blog.comments.all %}
<div class="comment">
<div class="date">{{ comment.created }}</div>
<strong>{{ comment.user }}</strong>
<p>{{ comment.text|linebreaks }}</p>
</div>
{% empty %}
<p>No comments here yet :(</p>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
You have called blog URL here ← 戻る and forgot to pass id inside your URL that's why it's showing this error
NoReverseMatch at /blogs/blog/30/ Reverse for 'blog' with no arguments not found. 1 pattern(s) tried: ['blogs/blog/(?P[0-9]+)/$']
you have to pass id here like this
← 戻る

'str' object has no attribute 'socialaccount_set' django allauth

I am trying to change my function based views to class based views
I have this profile view as function based:
#verified_email_required
#login_required
def profile(request, username):
if request.method == 'POST':
u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
if u_form.is_valid and p_form.is_valid():
u_form.save()
p_form.save()
message = messages.success(request, f'Your profile has been updated')
return redirect('profile', username=username)
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile)
try:
profile = User.objects.get(username=username)
except User.DoesNotExist:
message = messages.warning(request,f'Profile not found for {username}')
return redirect('home')
profile = ''
all_post_by_user = Log.objects.filter(author__username=username)
context = {
'u_form' : u_form,
'p_form' : p_form,
'profile' : profile,
'all_post_by_user' : all_post_by_user
}
return render(request, 'users/profile.html', context)
And this is my class based for the same :
class ProfileDetailView(DetailView):
model = Profile
template_name = "users/profile.html"
context_object_name = 'profile'
def get_object(self):
username = self.kwargs.get('username')
view_profile = Profile.objects.get(user__username=username)
So, I am getting this error:
profile.html:
{% extends 'log/base.html' %}
{% block content %}
{% load socialaccount %}
{% get_social_accounts profile as accounts %}
{%load crispy_forms_tags %}
<title>Error logger - Profile {{ profile.username }}</title>
<div id='profile' class="content-section card p-4">
<div class="media">
{% if profile.username == user.username %}
{% if accounts %}
<img class='rounded-circle account-img' src="{{ profile.socialaccount_set.all.0.get_avatar_url }}" />
{% else %}
<img class="rounded-circle account-img" src="{{ profile.profile.avatar.url }}">
{% endif %}
{% else %}
{% if accounts %}
<img class='rounded-circle account-img' src="{{ profile.socialaccount_set.all.0.get_avatar_url }}" />
{% else %}
<img class="rounded-circle account-img" src="{{ profile.profile.avatar.url }}">
{% endif %}
{% endif %}
<div class="media-body">
<h2 class="account-heading">{{profile.username}}</h2>
<p >{{profile.email}}</p>
<p>Created on: {{ profile.profile.created }}</p>
{% if profile.username == user.username %}
<p>Last updated on : {{ profile.profile.updated }}</p>
{% endif %}
</div>
</div>
<!-- FORM HERE -->
{% if profile.username == user.username %}
<form method='POST' autocomplete="off" enctype="multipart/form-data" >
{% csrf_token %}
<fieldset class='form-group'>
<legend class='border-bottom mb-4'>Update Profile</legend>
{{ u_form | crispy }}
{{ p_form | crispy }}
</fieldset>
<div class='form-group'>
<button class='btn btn-outline-info' type='submit'>Update</button>
</div>
</form>
{% endif %}
<div class="container border-top mt-4 pt-4">
<legend>Posts</legend>
{% for i in all_post_by_user %}
<div id="you-want-lazyload" data-lazyload="<p>Anything you want to lazyload</p>" class='m-4'>
<div class="container main m-4" style="width: 50vw;">
<a class='link' href="{% url 'log-detail' i.slug %}"><h2 >{{ i.title }}</h2></a>
<p>{{ i.content }}</p>
<p class='small'>{{ i.created }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
How to solve the error that I am getting?
I am using django allauth for social login with google
Also can someone explain why I have to query it is user__username=username?
Thanks
Ok, so the error tells us that you've got a string somewhere you aren't expecting it, because you're trying to access an attribute of a variable that is provided by allauth.
This is happening due to your exception handling here;
try:
profile = User.objects.get(username=username)
except User.DoesNotExist:
message = messages.warning(request, f'Profile not found for {username}')
return redirect('home')
profile = ''
If a user doesn't exist, you set profile to an empty string and that gets passed in the context.
So I'd change this a little bit, to fix this error and also to avoid the confusion of looking up User objects and calling them profile (I'd assume a User to be called user or similar)
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
message = messages.warning(request, f'User not found for {username}')
return redirect('home')
user = None
all_post_by_user = Log.objects.filter(author__username=username)
context = {
'u_form' : u_form,
'p_form' : p_form,
'user' : user,
'all_post_by_user' : all_post_by_user
}
return render(request, 'users/profile.html', context)
profile.html:
{% extends 'log/base.html' %}
{% load crispy_forms_tags socialaccount %}
{% block content %}
{% get_social_accounts profile as accounts %}
<title>Error logger - Profile {{ profile.username }}</title>
<div id='profile' class="content-section card p-4">
<div class="media">
{% if profile and profile.username == user.username %}
{% if accounts %}
<img class='rounded-circle account-img' src="{{ profile.socialaccount_set.all.0.get_avatar_url }}" />
{% else %}
<img class="rounded-circle account-img" src="{{ profile.profile.avatar.url }}">
{% endif %}
{% else %}
{% if accounts and profile %}
<img class='rounded-circle account-img' src="{{ profile.socialaccount_set.all.0.get_avatar_url }}" />
{% elif profile %}
<img class="rounded-circle account-img" src="{{ profile.profile.avatar.url }}">
{% endif %}
{% endif %}
{% if profile %}
<div class="media-body">
<h2 class="account-heading">{{profile.username}}</h2>
<p >{{profile.email}}</p>
<p>Created on: {{ profile.profile.created }}</p>
{% if profile.username == user.username %}
<p>Last updated on : {{ profile.profile.updated }}</p>
{% endif %}
</div>
</div>
<!-- FORM HERE -->
{% if profile.username == user.username %}
<form method='POST' autocomplete="off" enctype="multipart/form-data" >
{% csrf_token %}
<fieldset class='form-group'>
<legend class='border-bottom mb-4'>Update Profile</legend>
{{ u_form | crispy }}
{{ p_form | crispy }}
</fieldset>
<div class='form-group'>
<button class='btn btn-outline-info' type='submit'>Update</button>
</div>
</form>
{% endif %} <!-- end username check -->
{% endif %} <!-- end profile check -->
<div class="container border-top mt-4 pt-4">
<legend>Posts</legend>
{% for i in all_post_by_user %}
<div id="you-want-lazyload" data-lazyload="<p>Anything you want to lazyload</p>" class='m-4'>
<div class="container main m-4" style="width: 50vw;">
<a class='link' href="{% url 'log-detail' i.slug %}"><h2 >{{ i.title }}</h2></a>
<p>{{ i.content }}</p>
<p class='small'>{{ i.created }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}

Django redirect to specific URL after Registration

Good day.
I'm trying to redirect a user to specific url which in my case is rootPath/dashboard/
But when the user registers i get redirected to /user/register/dashboard/
I have searched other stackoverflow topics on same problem but they didn't resolve my problem.
I have defined these settings in settings.py
LOGIN_URL = 'user/login/'
LOGOUT_URL = 'user/logout/'
LOGIN_REDIRECT_URL = 'dashboard/'
views.py
def register(request):
form = RegisterForm(request.POST or None)
if request.POST:
if form.is_valid():
data = form.cleaned_data
email = data['email']
pwd = data['password']
user = User(email=email, password=pwd)
user.save()
return redirect(settings.LOGIN_REDIRECT_URL)
return render(request, 'registration/register.html', context={'form': form})
#login_required
def dashboard(request):
return render(request, 'user/dashboard.html')
urls.py
urlpatterns = [
path('user/login/', CustomLoginView.as_view(), name='login'),
path('user/logout/', auth_logout, name='logout'),
path('user/register/', register, name='register'),
path('dashboard/', dashboard, name='dashboard')
]
register.html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div class="container text-center">
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
<h1 class="h3 mb-3 font-weight-normal">Register</h1>
<form class="form-signin" action="." method="post">
{{ form.as_p }}
{% csrf_token %}
<p><input type="submit" value="Register" class="btn btn-primary"></p>
{# <input type="button" value="Forgot Password">#}
</form>
</div>
{% endblock %}
You can redirect to any specific url with redirect like this
return redirect('dashboard') #return redirect('url_name')
if the app_name is provided it would be like this
return redirect('app_name:url_name')

django-registration, registration and login form on index page together, did I do it right?

I'd appreciate some code review, I used django-registration app and django.contrib.auth module. What I wanted to do is have both the login and registration form on the index page, and manage it from there. What I did is I just copied code from registration.views.py and contrib.auth.views.py and banged it together.
It works but I feel it's very hack-ish, non elegant, and that there is another, proper way to do it. For example I feel it might be better to call or extend view methods in registration and auth instead of copy pasting them.
def index(request, success_url=None,
form_class=RegistrationForm,
authentication_form=AuthenticationForm,
profile_callback=None,
template_name='index.html',
extra_context=None, **kwargs):
redirect_to = request.REQUEST.get('next', '')
if request.method == 'POST':
form = form_class(data=request.POST, files=request.FILES)
form_auth = authentication_form(data=request.POST)
if form.is_valid():
new_user = form.save(profile_callback=profile_callback)
# success_url needs to be dynamically generated here; setting a
# a default value using reverse() will cause circular-import
# problems with the default URLConf for this application, which
# imports this file.
return HttpResponseRedirect(success_url or reverse('registration_complete'))
if form_auth.is_valid():
netloc = urlparse.urlparse(redirect_to)[1]
# Use default setting if redirect_to is empty
if not redirect_to:
#redirect_to = settings.LOGIN_REDIRECT_URL
redirect_to = "/"
# Security check -- don't allow redirection to a different
# host.
elif netloc and netloc != request.get_host():
#redirect_to = settings.LOGIN_REDIRECT_URL
redirect_to = "/"
# Okay, security checks complete. Log the user in.
auth_login(request, form_auth.get_user())
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
return HttpResponseRedirect(redirect_to)
else:
form = form_class()
form_auth = authentication_form()
if extra_context is None:
extra_context = {}
context = RequestContext(request)
for key, value in extra_context.items():
context[key] = callable(value) and value() or value
return render_to_response(template_name,
{ 'form': form, 'form_auth': form_auth},
context_instance=context)
And forms in the index.html:
{% if form.errors %}
<p class="errors">Please correct the errors below: {{ form.non_field_errors }}</p>
{% endif %}
<h3>Create an account</h3>
<form method="post" action="" class="wide">
{% csrf_token %}
<p>
<label for="id_username">Your Username:</label>
{% if form.username.errors %}
<p class="errors">{{ form.username.errors.as_text }}</p>
{% endif %}
{{ form.username }}
</p>
<p>
<label for="id_email">Email address:</label>
{% if form.email.errors %}
<p class="errors">{{ form.email.errors.as_text }}</p>
{% endif %}
{{ form.email }}
</p>
<p>
<label for="id_password1">Password:</label>
{% if form.password1.errors %}
<p class="errors">{{ form.password1.errors.as_text }}</p>
{% endif %}
{{ form.password1 }}
</p>
<p>
<label for="id_password2">Password (type again to catch typos):</label>
{% if form.password2.errors %}
<p class="errors">{{ form.password2.errors.as_text }}</p>
{% endif %}
{{ form.password2 }}
</p>
<p class="submit"><input type="submit" value="Register"></p>
</form>
{% if form_auth.errors %}
<p class="error">Please correct the errors below:</p>
{% endif %}
<h3>Log in</h3>
<form method="post" action="?next={{ next|default:"/" }}">
{% csrf_token %}
<dl>
<dt><label for="id_username">Username:</label>{% if form.username.errors %} <span class="error">{{ form.username.errors|join:", " }}</span>{% endif %}</dt>
<dd>{{ form_auth.username }}</dd>
<dt><label for="id_password">Password:</label>{% if form.password.errors %} <span class="error">{{ form.password.errors|join:", " }}</span>{% endif %}</dt>
<dd>{{ form_auth.password }}</dd>
<dt><input type="submit" value="Log in" /></dt>
</dl>
</form>
It's quite natural to place login or registration form at index page (or on every page), but why do you need to process the forms there? Process login on /auth/login/, process registration on /auth/registration/ and your code will be clean and extendable.