django forms, not valid - python

so no matter what I seem to do I can't get a valid form from just a integer field.
Controller:
def upload_image(request):
if request.method == "POST":
form = AddFloorplan(request.POST, request.FILES)
print request.POST.get('floornumber')
if form.is_valid():
print 'valid'
else:
print(form.errors)
return redirect("/wayfinder/editor/")
Form:
class AddFloorplan(forms.Form):
floor_number = forms.IntegerField(required=True)
Template:
<form action="/wayfinder/addfloorplan/" method="POST" enctype="multipart/form-data"> {% csrf_token %}
<div class="input-field col s12">
<input id="floornumber" autofocus name="floornumber" placeholder="Floor Number" type="text" required>
</div>
<div class="col s12">
<p>
<button class="btn waves-effect waves-light z-depth-0" type="submit" name="action">
<span>Upload</span>
</button>
</p>
</div>
</form>
had no luck passing the values

The name of your form field, floor_number
floor_number = forms.IntegerField(required=True)
does not match the name of your form input, floornumber
<input id="floornumber" autofocus name="floornumber" placeholder="Floor Number" type="text" required>
You need to use the same name in both places.

Related

Django form doesn't send data

I am trying to add a user to some events in the calendar (using fullcalendar), but when putting the form to request the data from the user, this form does not send me the data. How can I get the data it is supposed to send?
This is my event_register.html:
<div class="col-xl-6">
<p>Apuntarse como invitado.</p>
<form action="" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="first_name">Nombre:</label>
<!--<input id="first_name" name="first_name" placeholder="Nombre del participante" type="text" required="required" class="form-control">-->
<div class="input-group">
{{form.first_name}}
</div>
</div>
<div class="form-group">
<label for="last_name">Apellidos:</label>
<!--<input id="last_name" name="last_name" placeholder="Apellidos del participante" type="text" required="required" class="form-control">-->
<div class="input-group">
{{form.last_name}}
</div>
</div>
<div class="form-group">
<label for="phone">Teléfono:</label>
<!--<input id="phone" name="phone" placeholder="Teléfono del participante" type="text" required="required" class="form-control">-->
<div class="input-group">
{{form.phone}}
</div>
</div>
<div class="form-group">
<label for="email">Correo electrónico:</label>
<!--<input id="email" name="email" placeholder="Correo electrónico del participante" type="text" required="required" class="form-control">-->
<div class="input-group">
{{form.email}}
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary btn-block py-2" value="Enviar">
</div>
</form>
</div>
<div class="col-xl-6">
</div>
This is my view.py:
def attend_to(request):
event_form = EventForm()
print('Hola')
if request.method == 'POST':
event_form = EventForm(data=request.POST)
if event_form.is_valid():
Assistant.objects.create(UserManegement=None, Event=request.event_id, frist_name=request.POST["first_name"], last_name=request.POST["last_name"], phone=request.POST["phone"], email=request.POST["email"])
return render(request, "core/home.html")
else:
Assistant.objects.create(UserManegement=request.POST["user"], Event=request.POST["event"])
return render( "core/home.html")
This is my forms.py:
from django import forms
class EventForm(forms.Form):
first_name = forms.CharField(label="first_name", required=True, widget=forms.TextInput(
attrs={'class':'form-control', 'placeholder':'Escribe tu nombre'}
), min_length=3, max_length=100)
last_name = forms.CharField(label="last_name", required=True, widget=forms.TextInput(
attrs={'class':'form-control', 'placeholder':'Apellidos'}
), min_length=3, max_length=100)
phone = forms.CharField(label="phone", required=True, widget=forms.TextInput(
attrs={'class':'form-control', 'placeholder':'Telefono'}
), min_length=9, max_length=9)
email = forms.EmailField(label="Email", required=True, widget=forms.EmailInput(
attrs={'class':'form-control', 'placeholder':'Escribe tu email'}
), min_length=3, max_length=100)
This is my urls.py:
urlpatterns = [
path('', views.attend_to, name='attend_to'),
]
And this is what I receive when clicking on the button:
"POST /event/1/ HTTP/1.1" 200 6249
This is the view that renders the event_register.html view, I have a calendar with fullcalendar and when clicking on an event it shows me that template.
def register_event(request, event_id):
event = get_object_or_404(Event, id=event_id)
return render(request, "events/event_register.html", {'event':event})
Thanks in advance.
Edit 1:
I don't know what the problem is now, but when I click on the event to open the url that contains the form, it doesn't show me the corresponding template. It is as if it did not enter the if request.method == 'POST'. Here I leave the updated code.
The view what renders the template event_register.html:
def register_event(request, event_id):
event_form = EventForm()
event = get_object_or_404(Event, id=event_id)
return render(request, "events/event_register.html", {'event':event,
'form':event_form})
The template what contains the form:
<form action="{% url 'attend_to' %}" method="POST">
{% csrf_token %}
<div class="form-group">
<label for="first_name">Nombre:</label>
<!--<input id="first_name" name="first_name" placeholder="Nombre del participante" type="text" required="required" class="form-control">-->
<div class="input-group">
{{form.frist_name}}
</div>
</div>
urls.py core to load the template:
urlpatterns = [
#Path del core
path('', views.home, name='home'),
path('about/', views.about, name='about'),
path('event/<int:event_id>/', include('events.urls'), name='attend_to'),
]
urls.py for events:
urlpatterns = [
path('', views.attend_to, name='attend_to'),
]
The views.py what contains attend_to, it's show me the print('Hola'):
def attend_to(request, event_id):
event_form = EventForm()
print('Hola')
if request.method == 'POST':
event_form = EventForm(request.POST)
if event_form.is_valid():
event_form.save()
context = {"form":event_form}
Assistant.objects.create(UserManegement=None, Event=request.event_id, frist_name=context.first_name, last_name=context.last_name, phone=context.phone, email=context.email)
#Assistant.objects.create(UserManegement=None, Event=request.event_id, frist_name=request.POST["first_name"], last_name=request.POST["last_name"], phone=request.POST["phone"], email=request.POST["email"])
#return render(request, "core/home.html")
return HttpResponseRedirect('/')
#return render("core/home.html", context)
#else:
# Assistant.objects.create(UserManegement=request.POST["user"], Event=request.POST["event"])
# return render( "core/home.html")
else:
event_form = EventForm()
return render(request, 'core/home.html', {'form': event_form})
The response what shows me the server:
[24/Feb/2021 10:27:05] "GET / HTTP/1.1" 200 9404
Hola
Use Model Form instead of form.Forms
class EventForm(forms.ModelForm):
class Meta:
model = In which You want to save data
fields = "__all__" If you want to select all fields from your model or you can specify the list of fields in a list or tuple
fields = ("field1","Field2","field3")
This form will automatically map all your Model Field to HTML
and just render this form in HTML.In View also you dont need to write so much code
def attend_to(request):
event_form = EventForm()
if request.method == 'POST':
event_form = EventForm(request.POST)
if event_form.is_valid():
event_form.save()
return redirect()#After Form submission use redirect.Never use render as it can create duplicate enteries on refresh.
context = {"form":event_form}#Passing the form in HTML
return render( "core/home.html",context)
HTML
{% csrf_token %}
<div class="form-group">
<label for="first_name">Nombre:</label>
{{form.fieldname}}
<div class="input-group">
{{form.first_name}}
</div>
</div>
<div class="form-group">
<label for="last_name">Apellidos:</label>
<!--<input id="last_name" name="last_name" placeholder="Apellidos del participante" type="text" required="required" class="form-control">-->
<div class="input-group">
{{form.last_name}}
</div>
</div>
<div class="form-group">
<label for="phone">Teléfono:</label>
<!--<input id="phone" name="phone" placeholder="Teléfono del participante" type="text" required="required" class="form-control">-->
<div class="input-group">
{{form.phone}}
</div>
</div>
<div class="form-group">
<label for="email">Correo electrónico:</label>
<!--<input id="email" name="email" placeholder="Correo electrónico del participante" type="text" required="required" class="form-control">-->
<div class="input-group">
{{form.email}}
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary btn-block py-2" value="Enviar">
</div>
</form>
You can use load_widget_tweaks to style your form instead of writing code in your form
Add the blank form in the register_event view function.
def register_event(request, event_id):
event_form = EventForm()
event = get_object_or_404(Event, id=event_id)
return render(request, "events/event_register.html", {'event':event, 'form': event_form})
This will ensure the form fields are displayed in your event_register.html view that you can then submit.
Then in your form html, change the action attribute to submit the form data to the attend_to view function.
From this
<form action="" method="POST">
to this
<form action="{% url 'attend_to' %}" method="POST">

How to have single view for multiple HTML forms - Django

This is my view.So I want to keep 2 different HTML forms in same view ,But I am unable to do so beacuse whenever I add 1 form , I get the error of other on being none.
def home(request):
name = None
if request.method == 'POST':
name = request.POST.get('name')
choices = request.POST.get('choices')
subtest = request.POST.get('subtest')
reference = request.POST.get('reference')
unit = request.POST.get('unit')
test = Test()
test.name = name
test.save()
subtest = Subtest()
subtest.test = Test.objects.get(name=choices)
subtest.name = subtest
subtest.unit = unit
subtest.reference_value = reference
subtest.save()
# print(name)
return redirect('home')
return render(request,'main.html',{})
I have got 2 different forms . I didn't use django forms because I wanted to try something new.
MY FIRST FORM
<form method="POST">
{% csrf_token %}
<div class="icon-holder">
<i data-modal-target="test-popup" class="icon-cross"></i>
</div>
<div class="input-group">
<input type="text" name="name" placeholder="Test name" />
</div>
<div class="button-group">
<button type="submit">Submit</button>
</div>
</form>
MY SECOND FORM
<form method="POST">
{% csrf_token %}
<div class="icon-holder">
<i data-modal-target="menu-test-popup" class="icon-cross"></i>
</div>
<div class="input-group">
<label for="test-select">Test Name:</label>
<select name="choices" id="test-select">
{% for test in test %}
<option value="{{test.name}}" name='choices'>{{test.name|title}}</option>
{% endfor %}
</select>
</div>
<div class="input-group">
<input type="text" name="subtest" placeholder="SubTest name" />
</div>
<div class="input-group">
<input type="text" name="reference" placeholder="Reference rate" />
</div>
<div class="input-group">
<input type="text" name="unit" placeholder="Unit" />
</div>
<div class="button-group">
<button type="submit">Submit</button>
</div>
</form>
first form
<form method="POST">
...
<input name="form_type" value="first-form" type="hidden">
</form>
second form
<form method="POST">
...
<input name="form_type" value="second-form" type="hidden">
</form>
view function
def view(request):
if method == "POST":
form_type = request.POST.get('form_type')
if form_type == "first-form":
# first form's process
elif form_type == "second-form":
#second form's process
You have two forms here, when you submit the second form, only the fields from the second form gets submitted.
so from this line
name = request.POST.get('name')
name will become None. But I believe your Test model does not take any None value for name field( the reason for you " IntegrityError at / NOT NULL constraint failed: lab_test.name ").
To overcome this, first check if there is any value for 'name' then proceed with creating the test instance
if name:
test = Test()
test.name = name
test.save()
Similarly check if the other fields are present for the second form before creating and saving the instance.

Python Pyramid - Use session to pass form data to another page

I'm using Python Pyramid with Jinja2 template. I want to save my form data into session and retrieve it in another HTML page. How should I change in order to pass the data? I only know how to store the data I key in Views.py into session like this request.session['postal'] = 01934 but this is not the data I key in Delivery.jinja2. And if I used print (session['postal']), this will only show in my command prompt but not HTML page. Can anyone help me out? I'm a beginner to this.
What to add in/ change in my Views.py?
my HTML: Delivery.jinja2
<form class="form-horizontal" method="POST">
<div class="form-group">
<label class="control-label col-md-2" for="postal">Postal Code:</label>
<input type="text" class="form-control" id="postal" placeholder="Enter Postal Code" name="postal" />
</div>
<div class="form-group">
<label class="control-label col-md-2" for="address">Detailed Address:</label>
<textarea class="form-control" rows="3" id="address" placeholder="Enter Address" name="address"></textarea>
</div>
<div class="form-group">
<label class="control-label col-md-2" for="unit">Unit No #:</label>
<input type="text" class="form-control" id="unit" placeholder="Enter Unit No" name="unit" />
</div>
<button type="submit" class="btn btn-default" name="submit">Submit</button>
</form>
Views.py
#view_config(route_name='deliveryLink', renderer='templates/deliveryLink.jinja2')
def deliveryLink(request):
print("YAY for gift delivery via Link")
if 'submit_deliverylink' in request.POST:
print("request.POST: ", request.POST)
myform = request.POST
for m in myform:
print("key: ", m, " value: ", myform[m])
session = request.session
session['postal'] = ?
session['address'] = ?
session['unit'] = ?
data = "??"
data_array = data.split(",")
session['data'] = data_array
session['delivery'] = str(data_array)
print (session['delivery'])
return HTTPFound(location='http://localhost:5555/confirmation')
return {}
#view_config(route_name='confirmation', renderer='templates/confirmation.jinja2')
def confirmation(request):
print("YAY for confirmation")
for a in request.POST:
request.session[a] = request.POST[a]
return {}
and I want the data entered previously to show on this confirmation page: Confirmation.jinja2
<form class="form-horizontal" method="POST">
<div class="form-group">
<label class="control-label col-md-2" for="postal">Postal Code:</label>
<input type="text" class="form-control" id="postal" name="postal" />
</div>
<div class="form-group">
<label class="control-label col-md-2" for="address">Detailed Address:</label>
<textarea class="form-control" rows="3" id="address" name="address"></textarea>
</div>
<div class="form-group">
<label class="control-label col-md-2" for="unit">Unit No #:</label>
<input type="text" class="form-control" id="unit" name="unit" />
</div>
</form>
I think, you can just pass POST from initial form to template of confirmation page, without session.
If anyway you need session, you can call it from your template
<input type="text" class="form-control" id="postal" name="postal" value="{{session['postal']}}" />
# after form submitted, it sends post request, just check if it exist
if request.POST:
print("request.POST: ", request.POST)
myform = request.POST
# you need iterate over keys for this case
for m in myform.keys():
print("key: ", m, " value: ", myform[m])
session = request.session
# you can access request.POST directly or use your variable myfrom
# use myform.get('postal','') to get value by key
session['postal'] = myform.get('postal','')
session['address'] = myform.get('postal','')
session['unit'] = myform.get('unit','')
data = "??"
data_array = data.split(",")
session['data'] = data_array
session['delivery'] = str(data_array)
print (session['delivery'])
return HTTPFound(location='http://localhost:5555/confirmation')

Error of Django's forms instance

my files in project is:
djangoTry
--views.py
--forms.py
--others not included in this question files
When I click submit in my form I call this method from views.py:
from .forms import NameForm
def kontakt(request):
if request.method == 'POST':
form = NameForm(request.POST)
form.test("test")
if form.is_valid():
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
phone_number = form.cleaned_data['phone_number']
email = form.cleaned_data['email']
details = form.cleaned_data['details']
return HttpResponseRedirect('/')
else:
form = NameForm()
return render(request, 'index.html', {'form':form})
NameForm is class from forms.py file:
from django import forms
class NameForm(forms.Form):
first_name = forms.CharField(label='first_name', max_length=100)
last_name = forms.CharField(label='last_name', max_length=100)
phone_number = forms.CharField(label='phone_number', max_length=100)
email = forms.CharField(label='email', max_length=100)
details = forms.CharField(label='details', max_length=100)
def test(self, message):
print("i'm in test and message is: %s " , (message))
print(self.first_name)
def is_valid(self):
print("jest valid")
return True
form.html
<form class="col s12" action="{% url 'kontakt' %}" method="post">
{% csrf_token %}
{{ form }}
<div class="row">
<div class="input-field col s6">
<input
id="first_name"
type="text"
value="hehe">
<!-- value="{{ form.first_name }}"> -->
<label for="first_name">First name</label>
</div>
<div class="input-field col s6">
<input
id="last_name"
type="text"
autocomplete="off"
value="hehe">
<!-- value="{{ form.last_name }}" > -->
<label for="last_name">Last name</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input id="phone_number" type="number" autocomplete="off"
value="123456789">
<label for="phone_number">Phone number</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input id="email" type="email" autocomplete="off" value="rafald121#gmail.com" >
<label for="email">Email</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input id="details" type="text" autocomplete="off" value="qweqweqeq">
<label for="details">Details</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<a class="waves-effect waves-light btn">
<input id="submit" type="submit" >
<i class="material-icons right">send</i>
</a>
<!-- <input id="submit" type="submit" > -->
<label for="details">Details</label>
</div>
</div>
</form>
but everytime I get error:
AttributeError: 'NameForm' object has no attribute 'first_name'
but NameForm has "first_name" atribute
NameForm's method "test" work properly everytime but any of NameForm's variable can't be called.
Does anybody have idea what's going on ?

How can I reinsert a row using SQLAlchemy?

To add the item with the given description I use: db.session.add(new_item). To delete the item: db.session.query(Item).filter_by(item_id=new_id).delete(). To update some parts of the item: db.session.query(Item).filter_by(item_id=new_id).update({"status":"1 "}).
What should I use if I want to edit the item completely, that is, reinsert the data for the same item?
here is the code for the form:
<form class="form" action="{{ url_for('new_item') }}" method="post" role="form" enctype=multipart/form-data>
{{ form.csrf_token }}
<table>
<tr>
<td>
<div class="form-group">
<label for="item_name">item name:</label>
<input name="name" type="text" class="form-control" id="item_name">
</div>
</td>
<td>
<div class="form-group">
<label for="item_price">item price</label>
<input name="price" type="number" class="form-control" id="item_price">
</div>
</td>
<td>
<div class="form-group">
<label for="photo">Download the photo</label>
<input type="file" name="file">
<p class="help-block">Download</p>
</div>
</td>
</tr>
<tr>
<td>
<div class="form-group">
<label for="item_category">Category:</label>
<select name="category" class="form-control" id="item_category">
<option>LEGO</option>
<option>Игры_и_игрушки</option>
<option>Малыш</option>
<option>Школа_и_канцтовары</option>
<option>Творчество_и_развитие</option>
</select>
</div>
</td>
</tr>
</table>
<div class="form-group">
<label for="item_description">Description of the item:</label>
<textarea name="description" class="form-control" id="item_description" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-default">Save</button>
</form>
Here is the route for the form. There are others as well, to update the items and to delete it, but i guess this should be enough
#app.route('/admin_items', methods=['GET', 'POST'])
def admin_items():
form = AddItemForm(request.form)
available = db.session.query(Item).filter_by(status='1').order_by(Item.name.asc())
not_available = db.session.query(Item).filter_by(status='0').order_by(Item.name.asc())
return render_template('admin_items.html',
available_items=available,
not_available_items=not_available,
form=form)
#app.route('/add_item', methods=['GET', 'POST'])
#login_required
def new_item():
error = None
form = AddItemForm(request.form)
if request.method == 'POST':
file = request.files['file']
if file and allowed_file(file.filename) and form.name.data != "" and form.description.data != "":
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOADED_ITEMS_DEST'], filename))
new_item = Item(
filename,
form.name.data,
form.description.data,
form.price.data,
form.age.data,
form.particles.data,
form.category.data,
'1',
)
db.session.add(new_item)
db.session.commit()
return redirect(url_for('admin_items'))
else:
return render_template('admin_items.html', form=form, error=error)
if request.method == 'GET':
return redirect(url_for('admin_items'))
You can specify more elements to the update clause .update({"status":"1", "colour":"red"}) or you can grab the object from the database and just change it as required:
item = db.session.query(Item).get(1) # grab the item with PK #1.
item.status = '1'
item.colour = 'red'
db.session.commit() # commit your changes to the database.

Categories