Django is not taking input from html POST form - python

I have this html form:
<form method="post" action="">
{% csrf_token %}
<div class="inputText">
<input type="text" name="username" placeholder="Username" value = required />
<br><br>
<input type="email" name="email" placeholder="Email" required />
<br><br>
<input type="password" name="pass1" id="pass1" placeholder="Password" required />
<br><br>
<input type="password" name="pass2" id="pass2" onkeyup="checkPass(); return false;" placeholder="Confirm Password" required />
<br><br>
<span id="confirmMessage" class="confirmMessage"></span>
</div>
<div class="send">
<input type="submit" name="register" value="Register" class="register" />
</div>
This is my forms.py :
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ('username', 'email', 'password')
And my view
def register(request):
if request.method == "POST":
form = UserForm(request.POST)
if form.is_valid():
form.save
new_user = authenticate(username=request.POST['username'], password =request.POST['password'])
login(request.new_user)
return HttpResponseRedirect(request, '/index')
else:
form = UserForm()
return render(request, 'authen/register.html', {'form': form})
This should be a register system but when I press register it reloads the register page and nothing. When I go to django admin I see no new user so django is not taking input from form fields.

The form is presumably not valid, but you are not displaying any errors in your template. At least do {{ form.errors }} somewhere, although really you should output all the fields and their errors from the Django form directly:
{{ form.username }}
{{ form.username.errors }}
etc.
Also note you are not actually invoking the save method in your is_valid block. You need to do:
form.save()

Be sure to get the input element by its name attribute. This is because request.POST['keyword'] refers to the element identified by the specified html name attribute keyword.
Here's an example:
<form action="/login/" method="POST">
<input type="text" name="keyword" placeholder="Search query">
<input type="number" name="results" placeholder="Number of results">
</form>
In your Python file, where you get the value of the input elements, request.POST['keyword'] and request.POST['results'] will contain the values of keyword and results, respectively.

Related

Is it possible to fill out the fields of Django's UserCreationForm in python function?

I already have a Registration form on my ecommerce site. Now i would like to use Django's inbuilt validation system. Therefore, as far as i understood, i have to use a form that is provided by Django, e.g. UserCreationForm. But since i already have a form, i thought i could transfer the user information from my own form into some Django form in the backend. I have tried the following:
forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class RegistrationForm(UserCreationForm):
email = forms.EmailField(max_length=60)
class Meta:
model = User
fields = ("username", "email", "password1", "password2", "first_name", "last_name")
utils.py, containing the function, that is going to be called in views.py:
# does not return anything, since form.save() handles registration
def signup(request):
form = RegistrationForm()
# transfer the data from my_custom_view to Django's UserCreationForm
form.fields["username"].value = request.POST["username"]
form.fields["first_name"].value = request.POST["firstname"]
form.fields["last_name"].value = request.POST["lastname"]
form.fields["email"].value = request.POST["email"]
form.fields["password1"].value = request.POST["password"]
form.fields["password2"].value = request.POST["password_val"]
if form.is_valid():
# some message
form.save()
function above is called within views.py as follows:
home_view(request):
# some code
if request.method == "POST" and "signupbtn" in request.POST:
signup(request)
register.html:
<form class="px-4 py-3" method="POST">
{% csrf_token %}
<div class="container">
<input required class="form-control" type="text" name="firstname"
placeholder="First Name">
<input required class="form-control" type="text" name="lastname"
placeholder="Last Name">
</div>
</br>
<div class="container">
<input required class="form-control" type="text" name="username"
placeholder="Username">
<input required class="form-control" type="email" name="email"
placeholder="example#email.com">
<input required class="form-control" type="password" name="password"
placeholder="Password">
<input required class="form-control" type="password" name="password_val"
placeholder="Repeat Your Password">
</div>
<hr class="my-4">
<div class="d-grid">
<button class="btn btn-primary btn-login text-uppercase fw-bold" type="submit" name="signupbtn">Sign Up</button>
</div>
</form>
Whatever i try, form.is_valid() returned always False.
There is no specific reason i'm handling the registration this way. Alternatives might be Django-bootstrap or step by step rendering of UserCreationForm. I had this idea and i thought there has to be a way, right?

How to extract value from Radio Button in views.py in django from request.POST method

I'm trying to get value of a Radio Button from HTML template into views.py file for storing it inside my model. The problem is that it returns "on" always, and I'm using "request.POST['btnradio']" method to get the value/label of my radio button which has name="btnradio" in views.py file. I want it to return that the value/label of that button which is checked. Like if the button with value/label "Foodie" is checked, then it should return "Foodie" so that I can store it in modal. Likewise, if the other one is selected, then it should return "Restaurant".
This is my HTML template where I've written a form in which I'm trying to get value from a user signup.
<form action="" method="POST" name="signUpForm">
{% csrf_token %}
<input type="text" id="uname" name="userName" class="input-box" placeholder="User Name" required>
<input type="email" id="uemail" name="userEmail" class="input-box" placeholder="Email" required>
<input type="password" id="upass" name="userPass" class="input-box" placeholder="Password" pattern="^\S{6,}$" onchange="this.setCustomValidity(this.validity.patternMismatch ? 'Must have at least 6 characters' : ''); if(this.checkValidity()) form.ucpass.pattern = this.value;" required>
<input type="password" id="ucpass" name="userCpass" class="input-box" placeholder="Confirm Password" pattern="^\S{6,}$" onchange="this.setCustomValidity(this.validity.patternMismatch ? 'Please enter the same Password as above' : '');" required>
<div class="radio-btn-div btn-group" role="group" aria-label="Basic radio toggle button group">
<input type="radio" id="btnradio1" class="btn-check" name="btnradio" autocomplete="off" checked> <!-- This part I'm talking about -->
<label class="btn btn-outline-success" for="btnradio1">Foodie</label>
<input type="radio" id="btnradio2" class="btn-check" name="btnradio" autocomplete="off"> <!-- This is the second radio button -->
<label class="btn btn-outline-success" for="btnradio2">Restaurant</label>
</div>
<input type="submit" name="signupBtn" class="btn" value="Signup">
</form>
This is the views.py file.
def signup(request):
if request.method == 'POST':
username = request.POST['userName']
email = request.POST['userEmail']
password = request.POST['userPass']
cpass = request.POST['userCpass']
userType = request.POST['btnradio']
User.objects.create(username=username, email=email, password=password, userType=userType)
# and rest of the code is not important

Value Error when submitting form in Django mysql

I am getting a value error when submitting a form in Django. I have successfully connected the MySQL database in XAMPP. I can not find a solution to this.Here is my form code,
<form class="user" method="POST">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control form-control-user" id="Cus_name" name="Cus_name" placeholder="Enter Customer Name...">
</div>
<div class="form-group">
<input type="text" class="form-control form-control-user" id="Cus_address" name="Cus_address" placeholder="Enter Address... ">
</div>
<div class="form-group">
<input type="email" class="form-control form-control-user" id="Cus_email" placeholder="Enter Email Address...">
</div>
<div class="form-group">
<input type="text" class="form-control form-control-user" id="Purpose" placeholder="Enter Purpose...">
</div>
<div class="form-group">
<input type="date" class="form-control form-control-user" id="Date" placeholder="Enter Date...">
</div>
<div class="form-group">
<input type="time" class="form-control form-control-user" id="Time" placeholder="Enter Time...">
</div>
<div class="form-group">
<input type="text" class="form-control form-control-user" id="Venue" placeholder="Enter Venue...">
</div>
<button name="submit" type="submit" class="btn btn-success">Submit</button>
<hr>
</form>
Here is my Views.py
from django.shortcuts import render
from .models import AppointmentDet
from django.contrib import messages
def InsertDetails(request):
if request.method == 'POST':
if request.POST.get('Cus_name') and request.POST.get('Cus_address') and request.POST.get('Cus_email') and request.POST.get('Purpose') and request.POST.get('Date') and request.POST.get('Time') and request.POST.get('Venue'):
saverecord = AppointmentDet()
saverecord.Cus_name = request.POST.get('Cus_name')
saverecord.Cus_name = request.POST.get('Cus_address')
saverecord.Cus_name = request.POST.get('Cus_email')
saverecord.Cus_name = request.POST.get('Purpose')
saverecord.Cus_name = request.POST.get('Date')
saverecord.Cus_name = request.POST.get('Time')
saverecord.Cus_name = request.POST.get('Venue')
saverecord.save()
messages.success(request, "details saved successfully!")
return render(request, "appform.html")
else:
return render(request, "appform.html")
Here is the error I am getting when running the server.
ValueError at /
The view Management.views.InsertDetails didn't return an HttpResponse object. It returned None instead.
I tried some solutions but did not work.
You should read this little tutorial on how to work with forms:
https://docs.djangoproject.com/en/3.1/topics/forms/
When the data is sent, you should first cast the post into a form class object. Then you have to call "is_valid()" on said form.
Only after this method call the post data are in the object.
This is the example from django:
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})`

Two django ModelForms on the same page, same model, without Formset

I have two model forms on the same page. The form only has a single field, event that is selected:
forms.py
class RegistrationForm(forms.ModelForm):
class Meta:
model = Registration
fields = ['event']
views.py
form1 = RegistrationForm(request.POST or None, instance=user_reg1)
form2 = RegistrationForm(request.POST or None, instance=user_reg2)
if request.method == 'POST':
if form1.is_valid() and form2.is_valid():
form1.save()
form2.save()
.html
<form method="POST" action=""> {% csrf_token %}
{{ form1 }}
{{ form2 }}
<input type="submit" value="Save Selections"/>
</form>
The forms display and populates properly, but when I change the values and hit the save button, it always saves the form2 selection to both instances.
I've noticed that the DOM ids are the same, and I've been able to change the DOM id by grabbing a unique field in the Registration model (in this case, block)
form.py
class RegistrationForm(forms.ModelForm):
class Meta:
model = Registration
fields = ['event']
def __init__(self, *args, **kwargs):
block = kwargs.pop('block') # a unique field in the Registration model
super(RegistrationForm, self).__init__(*args, **kwargs)
if block:
DOM_id = "event-" + str(block)
self.fields['event'].widget.attrs.update({'id': DOM_id, })
This is giving the field a unique id, but both forms are still encompassed by a div with the same id: div_id_event
rendered html
<form method="POST" action=""> <input type='hidden' name='csrfmiddlewaretoken' value='...' />
<div id="div_id_event" class="form-group">
<label for="event-Flex-1" class="control-label requiredField">Event<span class="asteriskField">*</span> </label>
<div class="controls ">
<select class="select form-control" id="event-Flex-1" name="event" required>
<option value="">---------</option>
<option value="10">stuff</option>
...
</select>
</div>
</div>
<div id="div_id_event" class="form-group">
<label for="event-Flex-2" class="control-label requiredField">
Event<span class="asteriskField">*</span> </label>
<div class="controls ">
<select class="select form-control" id="event-Flex-2" name="event" required>
<option value="">---------</option>
<option value="10">stuff</option>
....
</select>
</div>
</div>
<input type="submit" value="Save Selections"/>
</form>
I don't even know if the id matters. Is there a way for me to get these two forms to cooperate without using a Formset?
The id of the DOM element is not important in this case. The important property is the name of the input element.
It sounds like you need to use the prefix attribute of the ModelForm. Check https://docs.djangoproject.com/en/2.0/ref/forms/api/#prefixes-for-forms.
Initialise the form with
form1 = RegistrationForm(request.POST or None, instance=user_reg1, prefix='user1')
form2 = RegistrationForm(request.POST or None, instance=user_reg2, prefix='user2')
You'll then end up with input element names prefixed with the value you gave for the prefix argument, which will prevent the namespace collision you are experiencing.

Django: Strange Formset behaviour after first submission

Long post ahead!
This is a follow-up to my previous question, which was about creating a feedback page that associates one form to each user. I was able to get that done, but it was done in what I guess is a hacked-together way because I'm seeing some really strange behaviour after I submit feedback one time.
Let's say I've not submitted any feedback previously, and now I want to submit feedback for two of three people (img). The hidden management_form details appear as follows:
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="3" />
<input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="0" />
<input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000" />
On submit this successfully creates two new entries in the Feedback table, as wanted. The problem is that now if I go to any feedback page (as any user) I see the feedback I have already created and I'll get errors on submit.
If I now go to a page with one or two users I'll see one or two forms (this is good) but the management_form data is incorrect. For example, on a one user page I'll see this management_form data:
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="3" />
<input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="2" />
<input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000" />
And get this error:
MultiValueDictKeyError at /feedback/2/
"u'form-1-id'"
Since I'm only supposed to have one form appear that's all I see, and it's set to the first of the two feedbacks already created, but there's obviously a problem with the management data. Initial should be 0 (not 2) and total forms should be 1 (not 3).
If I go to a page with an equal number of users I'll see the original three feedback forms, with this management_form data:
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="5" />
<input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="2" />
<input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000" />
Again, total should be 3 (not 5) and initial should be 0 (not 2). This time I don't get an error though, because I'll get a message saying that I need to fill in values for two forms which don't even appear on the page.
Hopefully that explains the problem well enough, so here's the code:
models.py
class Feedback(models.Model):
action = models.ForeignKey(Action)
feedback = models.CharField(max_length=1)
feedback_by = models.ForeignKey(UserProfile, related_name='feedback_by')
feedback_for = models.ForeignKey(UserProfile, related_name='feedback_for')
comment = models.CharField(max_length=200)
created = models.DateTimeField()
modified = models.DateTimeField()
def save(self, *args, **kwargs):
if not self.id:
self.created = datetime.datetime.today()
self.modified = datetime.datetime.today()
return super(Feedback, self).save(*args, **kwargs)
forms.py
class FeedbackForm(forms.ModelForm):
choices = (('g', '(+1) Positive'),
('b', '(±0) Negative'),
('n', '(-1) No Show'),
('d', 'Don\'t Leave Feedback'))
feedback = forms.ChoiceField(widget=forms.RadioSelect(), choices=choices, initial='d')
comment = forms.CharField(widget=forms.Textarea())
class Meta:
model = Feedback
fields = ['feedback_for','feedback','comment']
views.py
#login_required
def new_feedback(request, action_id):
action = get_object_or_404(Action, id=action_id)
profile = UserProfile.objects.get(user_id=request.user.id)
participants = all_info_many_profiles(action.participants.filter(~Q(id=profile.id)))
fbformset = modelformset_factory(Feedback, form=FeedbackForm, extra=len(participants))
if request.method == 'POST':
formset = fbformset(request.POST, request.FILES)
if formset.is_valid():
#formset.save(commit=False)
for form in formset:
tmp = form.save(commit=False)
tmp.action = action
tmp.feedback_by = profile
if tmp.feedback != 'd':
tmp.save()
return index(request)
else:
print formset.errors
#return index(request)
else:
formset = fbformset()
return render(request, 'app/new_feedback.html',
{'action': action, 'participants': participants, 'formset': formset}
)
feedback.html
{% load multifor %}
{% block body_block %}
<h1>Leave Feedback</h1>
<form method="post" action="{% url 'app:new_feedback' action.id%}">
{% csrf_token %}
{% comment %}
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="{{participants.count}}" />
<input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="0" />
<input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000" />
{% endcomment %}
{{ formset.management_form }}
{{ formset.errors }}
{% for form in formset; participant in participants %}
{{ form.id }}
{{ form.errors }}
<input id="id_form-{{forloop.counter0}}-feedback_for" name="form-{{forloop.counter0}}-feedback_for" type="hidden" value="{{participant.id}}" /> <br />
{{ form.feedback_for.label }} {{ participant.username }}: <br />
{% for radio in form.feedback %}
{{ radio }} <br />
{% endfor %}<br />
{{ form.comment.label }} {{ form.comment }} <br /><br />
{% endfor %}
<input type="submit" name="submit" value="Submit Feedback" />
</form>
{% endblock %}
The problem is that you are using a modelformset_factory, this factory is tied to the model and it will "help" you by populating stuff, this is why the count is at 5.
You might get the result you want by using a plain formset_factory. Django's docs has some examples

Categories