I am trying to wrap my head around how to use a tagging system with Flask and WTForms.
Basically I have a list of keywords. These keywords have a hierarchy (example: I select Chicago. Illinois and USA get automatically added as additional keywords).
So I'm trying to find a way for users to type into an autopopulating list. This form then produces the keywords and brings it back into flask, where each keyword is used as it's own variable.
With WTForms we need the "id" to bring back into Flask, but in a form like taggle.js or select2 how can we separate each tag into it's own id? Or are there better ways to go about this?
Flask
class ReusableForm(Form):
example4 = StringField('example4')
#app.route("/editor", methods=['GET', 'POST'])
def hello():
form = ReusableForm(request.form)
if request.method == 'POST':
example4 = request.form['example4']
if form.validate():
# Return and do something with each keyword
# tag1 = 'Alaska'
# tag2 = 'Hawaii'
# tag3 = 'California'
You need to use a dynamic form that will accept a variable number of tags being POSTed to Flask.
forms.py:
class TagForm(NoCsrfForm):
tag_id = IntegerField(widget=HiddenInput(), default=0)
tag_name = StringField(widget=HiddenInput(), [InputRequired(), Length(max=256)])
class MyDynamicForm(Form):
some_field = StringField('Foo', [InputRequired()])
some_other_field = TextAreaField('Bar', [InputRequired()])
some_tags = FieldList(FormField(TagForm))
views.py:
#app.route('/')
def index():
form = MyDynamicForm()
if form.validate_on_submit():
if len(form.some_tags.data) >= 1:
# Do something with the received tags.
pass
return render_template('index.html', form=form)
index.html
<input id="some_tags-0-tag_name"></input>
Each input id must use the following syntax: "[some_tags]-[nth tag]-[tag_name]". You should hopefully know best to create inputs and their ids taking into account the js frameworks you have available.
N.B. tag_id = IntegerField(widget=HiddenInput(), default=0) isn't necessary for receiving POSTed input but is useful if you store tags in a database and later want to populate the form with stored tags.
Related
I have 3 forms with Checkboxes to configure the desired form (Final_Form). After the user chooses the desired fields (in form1, form2 and form3), i want to delet all fields that are not required in the final form and render the final form. The reason for that is, that i have 3 Subkategories with around 12 possible values, in each form (form1-form3) the user can choose one ore more subkategories. The subcategories are standardized and are used to describe a clinical incident. The users wished to have the subcategories (1-3; form1-form3) seperated and always with an example (right-side of the screen in an anther bootstrap col).
The finalform is than a combination of the the subcategories that matches best to describe the clinical incident. All fields in the Final_Form are TextAreaFields. The Input for the TextAreaFields is stored in a sqlite-db.
Here is how i tried it:
app.py:
if request.method == 'POST' and form1.form1Submit.data:
OnePointOne = form1.OnePointOne.data
if not OnePointOne:
del Final_Form.OnePointOne
return render_template('Form2.html', form2 = form2)
if request.method == 'POST' and form2.form2Submit.data:
TwoPointTwo = form2.TwoPointTwo.data
if not TwoPointTwo:
del Final_Form.TwoPointTwo
return render_template('Form3.html', form3 = form3)
if request.method == 'POST' and form3.form3Submit.data:
ThreePointThree = form3.ThreePointThree.data
if not ThreePointThree:
del Final_Form.ThreePointThree
return render_template('Final.html', Final_Form = Final_Form)
forms.py:
class form1(FlaskForm):
OnePointOne = BooleanField('Effect')
form1Submit = SubmitField('Submit Category')
class form2(FlaskForm):
TwoPointTwo = BooleanField('Measure')
form2Submit = SubmitField('Submit Category')
class form3(FlaskForm):
ThreePointThree = BooleanField('Result')
form3Submit = SubmitField('Submit Category')
class Final_Form(FlaskForm):
OnePointOne = TextAreaField('Example Effect')
TwoPointTwo = TextAreaField('Example Measure')
ThreePointThree = TextAreaField('Example Result')
Final_FormSubmit = SubmitField('Submit incident')
The problem is, that the formfields of the Final_Form objects dont get deleted (only inside the if statements). I am very thankful for every hint or explanation.
As you are showing three separate pages, there are three separate requests.
You Final_Form object cannot be simply kept between these requests.
I don't fully understand why you configure your third form this way, it would be helpful to explain your use-case for better advice.
Without more information, I'm thinking of some ways to do this:
You make it one page/request, where you go from form to form using AJAX.
You make it one page with all forms, controlling visualisation with JS + CSS
You save your desired value somewhere
probably you can keep it in cookie (session object)
or in database, if that makes sense in your context
Also, please include whole code of this function - it's not clear how you create those forms you use.
I need to pass session id in URL query string after login using Django and Python but in my case I am getting some error. My code is below.
def loginsave(request):
"""This function helps to login the user """
if request.method == 'POST':
password = request.POST.get('pass')
uname = request.POST.get('uname')
per = User.objects.all().filter(
Q(password__icontains=password) & Q(uname__icontains=uname)).count()
if per > 0:
user = User.objects.filter(
Q(password__icontains=password) & Q(uname__icontains=uname))
for use in user:
uid = use.id
user_name = use.uname
request.session['id'] = uid
request.session['sess'] = dict(dt=str(datetime.now()),
value='session')
request.session['sess_id'] = 'abcd1234'
return render(request, 'bookingservice/home.html',
{'count': per, 'username': user_name})
else:
return render(request, 'bookingservice/login.html', {})
This is my login function here I am creating session id and I need to pass it over URL. My menu list is given below.
Home
Add Booking
Add Personal Info
I am doing like this but here I am getting the following error.
Exception Value:
Could not parse the remainder: '["sess_id"]' from 'request.session["sess_id"]'
Here I need after login the session id should come over every page URL.
Change
{{request.session["sess_id"]}}
to
{{ request.session.sess_id }}
usually the template language of django works this way. Here a dot in a variable name signifies a lookup.When the template system encounters a dot in a variable name, it tries the following lookups, in this order:
Dictionary lookup. Example: request.session["bar"]
Attribute lookup. Example: request.session.bar
List-index lookup. Example: request.session[bar]
You can find more at docs
You have an error in template, it should read (mind the quotes):
Home
Add Booking
Add Personal Info
I have a problem getting data from a form using it in a route
forms.py
class Calculator(Form):
amount = IntegerField('Amount')
weight = IntegerField('Weight')
class Program(Form):
cycles = IntegerField('Cycles')
volume = FormField(Calculator)
app.py
#app.route('/', methods=('GET', 'POST'))
def index():
form = forms.Program()
if form.validate_on_submit():
values = models.Progression(
cycles=form.cycles.data,
amount=form.amount.data,
weight=form.weight.data
)
return render_template('index.html', form=form, values=values)
The data for cycles comes through just fine but I am unsure of the syntax for how to access the encapsulated form within my route. The docs say FormField will return the data dict of the enclosed form but I can't seem to figure out how to grab that and put it in a variable.
I was able to grab the data I needed using
amount=form.volume.amount.data,
weight=form.volume.weight.data
The real issue came from the fact that the form was not validating when I was using FormField. A rookie error I should have checked earlier.
I had to enable CSRF protection by importing it from flask_wtf and using CsrfProtect(app)
The problem is that the form data does not come through as the attributes of the Calculator class. The data is sent as a dictionary from the volume attribute.
Test it out with: print form.volume.data
(I suggest commenting out your values object and just use print statements)
The output should be: {'amount': foo, 'weight': bar}
Thanks for teaching me something! I never knew of FormField.
I have been playing around with forms a little and cant seem to understand why cleaned_data is not giving me any usable output (aka the dict appears to be completely empty). What id like to do is have a form on a page with two date selector so the user can select a from and to date that Django will then query a database that has periodic thermocouple measurements and create a table.
views.py
def temperature_data(request):
date_select_form = CalLabDateSelect(request.POST)
if request.method == 'POST':
if date_select_form.is_valid(): # All validation rules pass
print "this should be some date/time data from date_select_form:", date_select_form.cleaned_data
#return HttpResponseRedirect('/test_page/') # Redirect after POST
raw_data = Callab.objects.all().using('devices').order_by('-time')
return render_to_response("temperature_display.html",
locals(),
context_instance=RequestContext(request))
forms.py
def make_custom_datefield(f):
formfield = f.formfield()
if isinstance(f, models.DateField):
formfield.widget.format = '%m/%d/%Y'
formfield.widget.attrs.update({'class':'datePicker', 'readonly':'true'})
return formfield
class CalLabDateSelect(forms.Form):
formfield_callback = make_custom_datefield
when i visit the page and select a date then submit the form i see this outputted to the console:
QueryDict: {u'date': [u'10/04/2014'], u'csrfmiddlewaretoken': [u'C5PPlMU3asdFwyma9azFDs4DN33CMmvK']}
this should be some date/time data from date_select_form: {}
all i notice is that the dictionary is empty {} but the request.POST data shows 10/04/2014???
any ideas why this is happening??
And thank you all very much for any help in understand this!!
Your form doesn't actually define any fields, so I don't know what you're expecting to get in cleaned_data. formfield_callback is only useful in a ModelForm, where it operates on the fields already defined by a model: but your form is not based on a model.
Either use a model form, or define your form fields explicitly in your form class.
I have an email form where I'm trying to save the user's email address to the database. The model looks like this:
class EmailForm(db.Model):
email_address = db.EmailProperty
I've been using a few tutorials like this as a guide where the data from the form is saved like this:
title = form.title.data,
content = form.content.data
when I follow the same convention, writing
email = form.email_address.data
there is an error that the EmailProperty does not have a data attribute.
I'm new to Google App Engine but I haven't found an answer in the docs. Thanks!
You are attempting to use a Model as a Form, which are two different things.
You need another step
from flaskext import wtf
from flaskext.wtf import validators
class EmailModel(db.Model):
email_address = db.EmailProperty
class EmailForm(wtf.Form):
email = wtf.TextField('Email Address', validators=[validators.Email()])
Now, in your view you can use the form like so.
#app.route('/register', methods=['POST']
def register():
form = EmailForm()
if form.validate_on_submit():
# This part saves the data from the form to the model.
email_model = EmailModel(email_address = form.email.data)
email.put()
I guess this is what you are looking for:
https://developers.google.com/appengine/docs/python/datastore/typesandpropertyclasses#Email
email_address = db.EmailProperty()
email_address = db.Email("larry#example.com")
You are using the old db class, use instead ndb, just replace db for ndb (https://docs.google.com/document/d/1AefylbadN456_Z7BZOpZEXDq8cR8LYu7QgI7bt5V0Iw/edit?ndplr=1&pli=1)
Use StringProperty instead EmailProperty, so..
class UserEmail(ndb.Model):
email_address = ndb.StringProperty()
To put models in datastore, do this
user = UserEmail(email_address='foobar#gmail.com')
user.put()