django custom login view (login as guest) - django

i am making an ecommerce and i have a checkout view in that view i have three forms : a login form a guest login form and a billing address form so basically if a user is logged in normally or as guest i am displaying the billing address form in the template 'checkout.html' otherwise i display the login form and the guest login form but these two forms are handled in different views checkout_login and guest_checkout_login so my question is : is it safe to do so ?
this is the checkout template :
{% if not billing_profile %}
<form method="post" action="{% url 'login_page' %}"> {% csrf_token %}
<input type="hidden" name="next" value="{{ request.build_absolute_uri }}">
{{ form }}
<button type="submit" class="btn btn-default">Submit</button>
</form>
<form method="post" action="{% url 'guest_login_page' %}"> {% csrf_token %}
<input type="hidden" name="next" value="{{ request.build_absolute_uri }}">
{{ guest_form }}
<button type="submit" class="btn btn-default">Submit</button>
</form>
{% else %}
<h1>checkout</h1>
billing profile:{{billing_profile}} </br>
<form method="post" action=".">{% csrf_token %}
{{ adress_form }}
<button type="submit" class="btn btn-default">Submit</button>
</form>
{% endif %}
{% endblock %}
this is the chekout_login view:
def login_page(request):
form = LoginForm(request.POST or None)
next_ = request.POST.get('next')
if request.method == 'POST':
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
if is_safe_url(next_, request.get_host()):
guest_email_id = request.session.get('guest_email_id')
if guest_email_id:
del request.session['guest_email_id']
return redirect(next_)
else:
return redirect("/")
else:
form = LoginForm()
return redirect("/")
if i am doing any mistake please tell me

Related

How can i Register and Login In The Same Page in Django?

i would like to have both my login form and my registration form on the same page within the same template, so i would like to have them under one view function but i am not too sure on how i can do that, here is my code.
Views.py
def register(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST) == "Register"
if form.is_valid():
form.save()
user = form.cleaned_data.get('username')
messages.success(request,"Account was Created for " + user)
context = {'form':form}
return render(request,'login.html',context)
def login(request):
if request.method == "POST":
if request.POST.get('submit') == 'Login':
username = request.POST.get('username')
password = request.POST.get('password1')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request,user)
return redirect('shop.html')
else:
messages.info(request, 'Wrong Username or password')
context = {}
return render(request,'shop.html',context)
login.html
<div class="formBx">
<form method="POST",name="Login",value="Login">
{% csrf_token %}
<h2>Sign In</h2>
{{form.username}}
{{form.password1}}
<input type="submit" name="submit" value="Login">
<p class="signup">Don't have an Account?Sign Up.</p>
{% for message in messages %}
<p id="messages">{{message}}</p>
{% endfor %}
</form>
</div>
</div>
<div class="user signUpBx">
<div class="formBx">
<form method="POST" value="Register">
{% csrf_token %}
<h2>Create an account</h2>
{{form.username}}
{{form.email}}
{{form.password1}}
{{form.password2}}
<input type="submit" name="submit" value="Register">
<p class="signup">Already Have an Account?Sign In.</p>
{% for message in messages %}
<p id="messages">{{message}}</p>
{% endfor %}
</form>
</div>
I'm getting AttributeError at /login/
'bool' object has no attribute 'is_valid' error right now.
You can use two separate forms for login and register in same view. Here is an example:
def register_login(request):
if "register" in request.method == "POST": #add the name "register" in your html button
..... your registration code
if "login" in request.method == "POST": #add the name "login" in your html button
..... your login code
**html**
<form>
{%csrf_token%}
.... your registration form
<button type="submit" name="register">register</button>
</form>
<form>
{%csrf_token%}
.... your login form
<button type="submit" name="login">register</button>
</form>

Django is not redirecting to profile page after login. What is wrong with my code?

This is my views.py
def LoginPage(request):
username = password = ''
next = ""
if request.GET:
next = request.GET['next']
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username = username, password = password)
if user is not None:
login(request, user)
if next == "":
return HttpResponseRedirect('/Profile/')
else:
return HttpResponseRedirect(next)
context = {}
return render(request, 'login.html', context)
This is my template:
{% if next %}
<form class="" action='/Profile/' method="post">
{%else%}
<form class="" action="/Login/" method="post">
{% endif %} {% csrf_token %}
<p class="login-field-title"><strong>Username*</strong></p>
<input type="text" class="form-control col-lg-10 log-inp-field" placeholder="Enter Username" required>
<p class="login-field-title"><strong>Password*</strong></p>
<input type="password" class="form-control col-lg-10 log-inp-field" placeholder="Enter Password" required> {% for message in messages %}
<p id="messages">{{message}}</p>
{% endfor %}
<button type="submit" class="btn btn-dark btn-lg col-lg-10 log-btn">Log In</button>
</form>
I don't understand what I'm doing wrong. Some help would be very appreciated. Even after logging in with a registered user it is not redirecting me to the desired page and when i change the action, even with the un registered user it redirects me to the next page.
Add this to your settings file
LOGIN_REDIRECT_URL = 'YOUR_PROFILE_URL'

How to use Two forms in Django Templates, And how to call different function when it submit the form

I am using two forms in one template. When i submit the 2nd form its calling first form only i'm little bit confusing where i did mistake anyone help me in this.
index.html
<form action="#" method="post">
{% csrf_token %}
<input type="text" name="username" id="username">
<button type="submit"> Submit</button>
</form>
<form action="#" method="post">
{% csrf_token %}
<input type="text" name="review" id="review">
<button type="submit"> Submit</button>
</form>
views.py
def profile(request):
if request.method == 'GET':
# Some operation
return render(request, 'index.html', {})
elif request.method == 'POST':
username = request.POST.get('username')
res = User(username=username)
res.save()
return redirect('/home/')
return redirect('/login/')
def feedback(request):
if request.method == 'POST':
review= request.POST.get('review')
res = Feedback(comment=review)
res.save()
return redirect('/home/')
return redirect('/home/')
urls.py
app_name = 'app'
urlpatterns = [
path('profile/', views.profile, name="profile"),
path('feedback/', views.feedback, name="feedback"),
]
I think the actions should be different to identify which form will make post request to which view:
<form action="{% url 'app:profile' %}" method="post">
{% csrf_token %}
<input type="text" name="username" id="username">
<button type="submit"> Submit</button>
</form>
<form action="{% url 'app:feedback' %}" method="post">
{% csrf_token %}
<input type="text" name="review" id="review">
<button type="submit"> Submit</button>
</form>
Add name attribute in submit.
<form action="#" method="post">
<input type="text" name="username" id="username">
<button type="submit" name="attr_name"> Submit</button>
</form>
And check the name in views.py
def profile(request):
if request.method == 'POST' and 'attr_name' in request.POST:
# Some operation

Use next parameter for login_required views

My method to redirect a url after login, work well but the code of the template is not very sexy, can I have yours please ?
my function in views.py
def connexion(request):
error = False
n=request.GET.get('n')
if request.method == "POST":
form = ConnexionForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username=username, password=password)
if user:
login(request, user)
if request.GET.get('n'):
return redirect(request.GET['n'])
else:
return redirect(accueil)
else:
error = True
else:
form = ConnexionForm()
return render(request, 'blog/connect_user.html', locals())
my template:
<h1>Se connecter</h1>
{% if error %}
<p><strong>Utilisateur inconnu ou mauvais mot de passe.</strong></p>
{% endif %}
{%if n %}
<form method="post" action="{% url 'connexion' %}?n={{ n }}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Se connecter" />
</form>
{% else %}
<form method="post" action="{% url 'connexion' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Se connecter" />
</form>
{% endif %}
my decorator:
#login_required(redirect_field_name='n')
Why not just:
<input type="hidden" name="n" value="{{ n }}">
And in the view:
n = request.REQUEST.get('n', '')
Using request.REQUEST you can get n from either using POST or GET so you can still link to a URL like /login?n=/foo/bar. You can also do POST/REDIRECT/GET without problems.

How insert 2 different forms on the same page in Django

I have to insert 2 forms in the same page:
1) Registration form
2) Login form
.
So if I use this in the views.py:
if request.method == 'POST':
form = registrationForm(request.POST)
if form.is_valid():
form.save()
return render_to_response('template.html', {
'form': form,
})
I will get error by submitting one of two forms.
How can I distinguish the 2 forms submitting in the views ?
You can also do like this,
<form method='POST'>
{{form1.as_p}}
<button type="submit" name="btnform1">Save Changes</button>
</form>
<form method='POST'>
{{form2.as_p}}
<button type="submit" name="btnform2">Save Changes</button>
</form>
CODE
if request.method=='POST' and 'btnform1' in request.POST:
do something...
if request.method=='POST' and 'btnform2' in request.POST:
do something...
You can submit two forms on the same page... but the action that each form calls (i.e. the view function that will process each form) should probably be different. That way, you won't have to try and distinguish the forms.
e.g. On your page:
<form id="login_form" action="{% url app.views.login %}" method="post">
...form fields...
</form>
<form id="registration_form" action="{% url app.views.registration %}" method="post">
...form fields...
</form>
And so, in views.py, you'll have a login() view function and a registration() view function that will handle each of those forms.
<form action="Page where u want to post the data" method="post">
<input name="edit" type="submit" value="Edit Client">
<input name="delete" type="submit" value="Delete Client">
</form>
just Give different names to the buttons.
if request.method == "POST" and 'edit' in request.POST:
/ Do /
if request.method == "POST" and 'delete' in request.POST:
/Do /
You can post both forms to same url too:
forms in template are like this:
<form method="post" action="/profile/">
{% for field in firstform %}
<div class="mb10">
<div class="fl desc">{{ field.label_tag }}<br />
<div class="fr">{{ field }}{{ field.errors }}</div>
<div class="clear"></div>
</div>
{% endfor %}
{% for field in secondform %}
<div class="mb10">
<div class="fl desc">{{ field.label_tag }}<br /><</div>
<div class="fr">{{ field }}{{ field.errors }}</div>
<div class="clear"></div>
</div>
{% endfor %}
<a class="submit fr" href="#""><img src="{{ MEDIA_URL }}img/save.png" /></a>
</form>
and just handle them like this in view:
if request.method == 'POST':
firstform = ProfileForm(request.POST, request.FILES, instance=profile)
secondform = UserForm(request.POST, instance=request.user)
and then do stuff with firstform&secondform.
You can have both forms posting to the same URL and have a hidden input with name set to login or registration and sort that out on the server
You can do the Registration and Login POST to different urls so each POST will be handled by corresponding view