Using django Authentication form with the html form - html

I am trying to build a login module in django. I already have a nice HTML form for login which has username and password field.
But in my views.py I have imported default Django AuthenticationForm, but if integrate it with my nice-looking HTML form, there will be two forms. How can I import the Authentication form and use it with the my HTML form??
My code is here:
My view:
def login(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
authlog(request, user)
return redirect('home')
else:
messages.error(request, 'Invalid username or password')
# back_page = request.META.get('HTTP_REFERER')
return redirect('login')
# return HttpResponse(back_page)
else:
content = {
'form': AuthenticationForm()
}
return render(request, 'sign-in.html', content)
If I use Django default form, the code will be following, but it won't look good as my other Html login page.
My sign-in html:
<hr>
<form action="" method="post">
{% csrf_token %}
{{form|crispy}}
<button type="submit" class=" btn btn-success ">Sign-Up</button>
</form>
I haven't posted my other HTML form though as it is very large. Hope it explains.

Related

How Do I Properly Submit Two Forms Within One HTML Structure?

I am trying to submit a create view with two forms. The code below works fine if everything is filled out and the form submitted. However if fields are omitted in form2...the form submission fails and the field that was filled out for "form"..."name"....gets reset. I've read you can do multiple forms and I've largely got this working...I just need to figure out how to incorporate form2 into the if_valid().... Here's my view...
def tasklist_detail_view(request, id):
context = {}
context["tasklist"] = TaskList.objects.get(id=id)
context["tasks"] = Task.objects.filter(task_list=id).all()
obj = get_object_or_404(TaskList, id=id)
form = UpdateTaskListForm(request.POST or None, instance=obj)
form2 = TaskForm(request.POST or None)
context["task_list_id"] = id
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse("MyTaskLists:my_task_list_main_menu"))
context["form"] = form
context["form2"] = form2
return render(request, "my_task_list_tasklist_detail.html", context)
My HTML...
<form method="POST" enctype="multipart/form-data" id="forms">
{% csrf_token %}
{{ form.name }}
{% include "my_task_list_task_create_form1.html" with tasklist=tasklist %}
<button type="submit" class="button66" name="status" value="Submitted">Submit</button>
</form>
And then in my include HTML...
<div id="task-list-form" hx-target="this" hx-swap="outerHTML">
<button class="button35" hx-post="{% url 'MyTaskLists:task-create' id=task_list_id %}">Save</button>
{{ form2 }}
I did try to do something like....
if form.is_valid() and form2.is_valid():
form.save()
return HttpResponseRedirect(reverse("MyTaskLists:my_task_list_main_menu"))
But then nothing happens...the forms are not accepted at all even if the fields are filled out properly....From what I've read I understand the POST is being applied to both forms....if one is not filled out properly that is why the other errors out? I just can't quite figure out how to process them both properly.
Thanks in advance for any thoughts.
If you want the two forms to behave like one form, and save two objects only if both forms are valid, then the logic is
if form.is_valid() and form2.is_valid():
form.save()
form2.save()
return HttpResponseRedirect(reverse("MyTaskLists:my_task_list_main_menu"))
context["form"] = form
context["form2"] = form2
return render(request, "my_task_list_tasklist_detail.html", context)
If there is any field with the same name in form and form2 you need to use a prefix to remove the ambiguity.
form = UpdateTaskListForm(request.POST or None, instance=obj, prefix='form1')
form2 = TaskForm(request.POST or None, prefix='form2')

Django ajax post method dont redirect

im following a tuto on how ajax work on Django, its my first time with ajax and im facing a little problem ,the data insertion is working but the success ajax dont redirect corectly, and thank you for the help
this the code
views.py :
class exo(View):
def get(self, request):
form = ExerciseForm()
tasks = task.objects.all()
context = {
'form': form,
'tasks': tasks
}
return render(request, 'coach/test.html',
context=context)
def post(self, request):
form = ExerciseForm()
if request.method == 'POST':
form = ExerciseForm(request.POST)
print(form)
if form.is_valid():
print('adding task', form)
new_exrercise = form.save()
return JsonResponse({'task': model_to_dict(new_exrercise)}, status=200 )
else:
print('not adding task')
return redirect('exo')
ajax function :
$(document).ready(function(){
$("#addExercise").click(function() {
var serializedData = $("#TaskForm").serialize();
$.ajax({
url: $("TaskForm").data('url'),
data : serializedData,
type: 'post',
success: function(response) {
$("#taskList").append('<div
class="card"><div class="card-body">'+ response.task.name
+'<button type="button" class="close float-right"> <span
aria-hidden="true">×</span></button></div></div>');
}
})
});
});
html content :
<form class="submit-form" method="post" id="TaskForm"
data-url="{% url 'session' %}">
{% csrf_token %}
<div class="form-group">
{% for field in form %}
<div style="margin-bottom: 2rem;"></div>
{{field}}
{% endfor %}
<div style="margin-bottom: 2rem;"></div>
<button type="submit" class="btn btn-success dropdown-toggle " id="addExercise">Confirm</button>
</div>
</form>
this is what i get (i get an object and nothing else )
output image
when i comeback to the page exo the insertion is done
and the console show me that the post is sending well :
[21/Dec/2020 22:25:38] "POST /coach/exo/ HTTP/1.1" 200 43
The problem is that your button:
<button type="submit" class="btn btn-success dropdown-toggle " id="addExercise">Confirm</button>
will submit the form, and not (only) by the AJAX call, but simply by the fact that you made it a submit button. This thus means that the browser will encode the form and make a POST request with that form, and then the browser will render the response.
You thus should remove the type="submit" part from the button:
<button class="btn btn-success dropdown-toggle " id="addExercise">Confirm</button>
I remove the submit type and nothing was working , the button wasnt posting anything to ajax then i switch my view class into a function and it work i really dont know why there is the view
def addsession(request):
template = loader.get_template('coach/addexercise.html')
exercises = exercise.objects.all()
# context = {'exercises': exercises}
UpperBody = exercise.objects.filter(category__name="Upper Body")
LowerBody = exercise.objects.filter(category__name="Lower Body")
FIIT = exercise.objects.filter(category__name="FIIT")
LIIT = exercise.objects.filter(category__name="LIIT")
form = ExerciseForm()
tasks = task.objects.all()
context = {'exercises': exercises,
'UpperBody': UpperBody,
'LowerBody': LowerBody,
'FIIT': FIIT,
'LIIT': LIIT,
'form': form,
'tasks': tasks
}
form = ExerciseForm()
if request.method == 'POST':
form = ExerciseForm(request.POST)
print(form)
if form.is_valid():
print('adding task', form)
new_exrercise = form.save()
return JsonResponse({'task': model_to_dict(new_exrercise)}, status=200 )
else:
print('not adding task')
return redirect('session')
return render(request, 'coach/addexercise.html', context=context)
and thank u guys for your answers i really didnt give attention to the input type of button

Issues in uploading image from user without django ModelForm

I am trying to create a form without using ModelForm. I using the input elements in HTML for the purpose (to upload name and image). But I am having trouble uploading images with this process.
The name is getting saved but not the image.
My code:
models.py
class Register(models.Model):
name = models.CharField(max_length=50, null=True)
idCard = models.FileField(upload_to='idCard', null=True)
views.py
def index(request):
if request.method == 'POST':
data.name = request.POST.get('name')
data.idCard = request.POST.get('idCard')
data.save()
return redirect('/')
return render(request, 'event/index.html')
index.html
<form class="mform" id="myform" method="POST" id="myform" action="" enctype="multipart/form-data">
{% csrf_token %}
<fieldset>
<legend>Registeration</legend>
<table cellspacing="0"><tbody>
<tr><td>
<label for="u_name"> Username :</label></td><td>
<input type="text" name="name" id="u_name">
<td>
</tr>
<tr><td>
<label for="u_img"> IDCard :</label></td><td>
<input type='file' accept='image/*' onchange='openFile(event)' name="idCard" id="u_img">
</td></tr>
The name is getting saved but not the image.
The files are stored in request.FILES:
def index(request):
if request.method == 'POST':
data.name = request.POST.get('name')
data.idCard = request.FILES.get('idCard')
data.save()
return redirect('/')
return render(request, 'event/index.html')
That being said, I strongly advise to use a Form (or ModelForm). A form does not just handle saving the object, it also performs proper validation, can return error messages, and removes a lot of boilerplate code. Often with some tweaking, you can let the form look like you want. But even if you manually write the form in the template, you can still use a form at the Django level to validate and save the object.

Invalid form when uploading file in Django

I need to upload file on a Django page, however, after following the official tutorial, I was not able to upload it, it always gives the error "invalid form", and when I tried to print out the error msg of the form, it says "This field is required".
One thing notable is: I have 2 forms on one page, one is this upload form and the other one is for filling out information. Not sure if this is the root cause.
I have tried all solutions provided on the Internet.
Template file:
<form id="uploadForm" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="file" value="upload" name="sourcefile">
<button type="submit">Upload</button>
</form>
Forms.py:
from django import forms
from .models import SourceFile
class UploadFileForm(forms.ModelForm):
class Meta:
model = SourceFile
fields = ('file', 'title')
Models.py:
from django.db import models
# Create your models here.
class SourceFile(models.Model):
title = models.CharField(max_length=255, blank=True)
file = models.FileField(upload_to="media/")
Views.py
def model_form_upload(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
instance = SourceFile(file_field=request.FILES['file'])
instance.save()
return JsonResponse({'error': False, 'message': 'Uploaded Successfully!'})
else:
print("Invalid form")
# return JsonResponse({'error': True, 'errors': form.errors})
else:
form = UploadFileForm()
return render(request, 'source_validation.html', {'form': form})
Your template is wrong. Either use {{ form.as_p }} which should display a file input field because file is a field in your form. (so remove the <input type="file" ...>)
Or don't use it and manually add the <input> fields, but then you must use the correct names. Your form expects a "file" parameter, not a "sourcefile" parameter:
<input type="file" name="file">
Also, you're overcomplicating things in your view (even though your current code will work if you fix your template):
if form.is_valid():
form.save() # this will save your model
return redirect(...)

Not able to post form data to action url

I have a login form. After pressing the login button the the post data is sent to the view login_auth that authenticates the user data and redirects accordingly. However,after pressing the login button, I am not being redirected to the appropriate page.
views.py
def login_successful(request):
return render(request,"login_successful.html")
def login_invalid(request):
return render(request,"login_invalid.html")
def login(request):
return render(request,'login.html',c)
def loginauth(request):
username=request.POST.get("username",'')
password=request.POST.get("password",'')
user=auth.authenticate(username=username,password=password)
if user is not none:
user.login(request.user)
return redirect(login_successful)
else:
return redirect(login_invalid)
urls.py
urlpatterns = [
url(r'^registration/',views.registration),
url(r'^registration_successful/',views.registration_successful),
url(r'^home/',views.home),
url(r'^login/',views.login),
url(r'^login_successful/',views.login_successful),
url(r'^login_invalid/',views.login_invalid),
url(r'^login/auth',views.loginauth)
]
login.html
<html>
<form action="/login/auth" method="POST">{% csrf_token %}
Username :<input type="textbox" name="username" >
Password :<input type="password" name="password">
<input type="submit" value="Login">
</form>
</html>
Your login url pattern is missing a trailing $. It should be:
url(r'^login/$', views.login),
Without the dollar, the /login/auth is matched by r'^login/, so the request is handled by your login view.
It's a bit unusual to process the form on a different url. Django comes with authentication views, including a login view. I would recommend using this rather than writing your own.
Use name for url
views.py
def login_successful(request):
return render(request,"login_successful.html")
def login_invalid(request):
return render(request,"login_invalid.html")
def login(request):
return render(request,'login.html',c)
def loginauth(request):
username=request.POST.get("username",'')
password=request.POST.get("password",'')
user=auth.authenticate(username=username,password=password)
if user is not none:
user.login(request.user)
return redirect('login_successful')
else:
return redirect('login_invalid')
urls.py
urlpatterns = [
url(r'^registration/',views.registration),
url(r'^registration_successful/',views.registration_successful),
url(r'^home/',views.home),
url(r'^login/$',views.login),
url(r'^login_successful/',views.login_successful, name='login_successful'),
url(r'^login_invalid/',views.login_invalid, name='login_invalid'),
url(r'^login/auth',views.loginauth)
]