Creating a bulb shape with selections from more than one table

I saw a large number of tutorials that display login forms with a flask and flash-wtf, but none of them contain multitasking fields from the values โ€‹โ€‹of the database table.

This is what I am trying to do:

Simple registration form:

Name

Surname

Address Line 1

Address bar 2

Town

State identifier (populated from the request of the state library Id, state)

Country identifier (country library request, id filled out from the country)

An example code or walk link will be appreciated.

+2
flask flask-wtforms
source share
1 answer

I tried to find an explanation of how to do this, and could not find it. Therefore, I am going to write here. This is how I do what there are probably ways to do this.

Source

You can download the full source code of this tutorial on my github account. I pretty much copy and paste from the source code, but just in case github someday we will leave.

Configuration

It is necessary to configure our application and connection to the database. In most cases, you probably want to download all of this from the configuration file.

In this tutorial, we are going to use the sqlalchemy core test database.

app = Flask(__name__) app.config['SECRET_KEY'] = 'Insert_random_string_here' 

Set this configuration to True if you want to see all generated SQL.

 app.config['SQLALCHEMY_ECHO'] = False app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' 

WTForms Configuration Lines

 app.config['WTF_CSRF_ENABLED'] = True 

CSRF marks are important. Read more about them here https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

 app.config['WTF_CSRF_SECRET_KEY'] = 'Insert_random_string_here' db = SQLAlchemy(app) 

SQLALchemy Model

Next, we need to create model classes that will be used during the creation of the database, as well as when we want to manipulate the database. This should usually be a separate separate file.

It matters to me as if it were its own separate file.

Usually you need to import something like from a db application import

 class RegisteredUser(db.Model): """ loads and pushes registered user data after they have signed up. SQLalchemy ORM table object which is used to load, and push, data from the server memory scope to, and from, the database scope. """ __tablename__ = "RegisteredUser" #all of the columns in the database. registered_id = db.Column(db.Integer, primary_key=True) first_name = db.Column(db.String(70)) last_name = db.Column(db.String(70)) address_line_one = db.Column(db.String(256)) address_line_two = db.Column(db.String(256)) city = db.Column(db.String(50)) """ Now we're going to create all of the foreign keys for the RegisteredUser table. The db.relationship section allows us to easily and automatically join the other tables with registeredUser. The Join will only take place if you attempt to access columns from the State or country table. For more on Foreign keys using SQLAlchemy go to """ state_id = db.Column( db.Integer, db.ForeignKey('State.state_id'), nullable=False) #retrives the users name for display purposes. state_by = db.relationship( 'State', foreign_keys=[state_id], backref=db.backref('State', lazy='dynamic')) country_id = db.Column( db.Integer, db.ForeignKey('Country.country_id'), nullable=False) #retrives the users name for display purposes. country_by = db.relationship( 'Country', foreign_keys=[country_id],) #this is the method and function style I've chosen when lines are too long def __init__( self, first_name, last_name, address_line_one, address_line_two, city, state_id, country_id): """ Used to create a RegisteredUser object in the python server scope We will be calling these init functions every time we use RegisteredUser() as a 'function' call. It will create a SQLalchemy ORM object for us. """ self.first_name = first_name self.last_name = last_name self.address_line_one = address_line_one self.address_line_two = address_line_two self.city = city self.state_id = state_id self.country_id = country_id class State(db.Model): # pylint: disable-msg=R0903 """ Holds State names for the database to load during the registration page. SQLalchemy ORM table object which is used to load, and push, data from the server memory scope to, and from, the database scope. """ __tablename__ = "State" state_id = db.Column(db.Integer, primary_key=True) state_name = db.Column(db.String(10), unique=True) def __init__(self, state_name): """ Used to create a State object in the python server scope """ self.state_name = state_name class Country(db.Model): # pylint: disable-msg=R0903 """ Holds Country names for the database to load during the registration page. SQLalchemy ORM table object which is used to load, and push, data from the server memory scope to, and from, the database scope. """ __tablename__ = "Country" country_id = db.Column(db.Integer, primary_key=True) #longest country length is currently 163 letters country_name = db.Column(db.String(256), unique=True) def __init__(self, country_name): """ Used to create a Country object in the python server scope """ self.country_name = country_name def create_example_data(): """ Generates all of the demo data to be used later in the tutorial. This is how we can use our ORM objects to push data to the database. NOTE: create_example_data is called at the very bottom of the file. """ #Create a bunch of state models and add them to the current session. #Note, this does not add rows to the database. We'll commit them later. state_model = State(state_name="WA") db.session.add(state_model) state_model = State(state_name="AK") db.session.add(state_model) state_model = State(state_name="LA") db.session.add(state_model) #Normally I load this data from very large CVS or json files and run This #sort of thing through a for loop. country_model = Country("USA") db.session.add(country_model) country_model = Country("Some_Made_Up_Place") db.session.add(country_model) # Interesting Note: things will be commited in reverse order from when they # were added. try: db.session.commit() except IntegrityError as e: print("attempted to push data to database. Not first run. continuing\ as normal") 

Wtform

Now we will create the WTForms objects. This data will have data from the database hosted on them, we will transfer it to our template files where we will make it.

It matters to me as if it were its own separate file.

 import wtforms import wtforms.validators as validators from flask.ext.wtf import Form class RegistrationForm(Form): """ This Form class contains all of the fileds that make up our registration Form. """ #Get all of the text fields out of the way. first_name_field = wtforms.TextField( label="First Name", validators=[validators.Length(max=70), validators.Required()]) last_name_field = wtforms.TextField( label="Last Name", validators=[validators.Length(max=70), validators.Required()]) address_line_one_field = wtforms.TextField( label="Address", validators=[validators.Length(max=256), validators.Required()]) address_line_two_field = wtforms.TextField( label="Second Address", validators=[validators.Length(max=256), ]) city_field = wtforms.TextField( label="City", validators=[validators.Length(max=50), validators.Required()]) # Now let set all of our select fields. state_select_field = wtforms.SelectField(label="State", coerce=int) country_select_field = wtforms.SelectField(label="Country", coerce=int) 

representation

bottle for import

 def populate_form_choices(registration_form): """ Pulls choices from the database to populate our select fields. """ states = State.query.all() countries = Country.query.all() state_names = [] for state in states: state_names.append(state.state_name) #choices need to come in the form of a list comprised of enumerated lists #example [('cpp', 'C++'), ('py', 'Python'), ('text', 'Plain Text')] state_choices = list(enumerate(state_names)) country_names = [] for country in countries: country_names.append(country.country_name) country_choices = list(enumerate(country_names)) #now that we've built our choices, we need to set them. registration_form.state_select_field.choices = state_choices registration_form.country_select_field.choices = country_choices @app.route('/', methods=['GET', 'POST']) def demonstration(): """ This will render a template that displays all of the form objects if it's a Get request. If the use is attempting to Post then this view will push the data to the database. """ #this parts a little hard to understand. flask-wtforms does an implicit #call each time you create a form object. It attempts to see if there a #request.form object in this session and if there is it adds the data from #the request to the form object. registration_form = RegistrationForm() #Before we attempt to validate our form data we have to set our select #field choices. This is just something you need to do if you're going to #use WTForms, even if it seems silly. populate_form_choices(registration_form) #This means that if we're not sending a post request then this if statement #will always fail. So then we just move on to render the template normally. if flask.request.method == 'POST' and registration_form.validate(): #If we're making a post request and we passed all the validators then #create a registered user model and push that model to the database. registered_user = RegisteredUser( first_name=registration_form.data['first_name_field'], last_name=registration_form.data['last_name_field'], address_line_one=registration_form.data['address_line_one_field'], address_line_two=registration_form.data['address_line_two_field'], city=registration_form.data['city_field'], state_id=registration_form.data['state_select_field'], country_id=registration_form.data['country_select_field'],) db.session.add(registered_user) db.session.commit() return flask.render_template( template_name_or_list='success.html', registration_form=registration_form,) return flask.render_template( template_name_or_list='registration.html', registration_form=registration_form,) 

runserver.py

Finally, this is for development purposes only. Usually I have this file called RunServer.py. To actually provide your application, you need some kind of web server (Apache, Nginix, Heroku).

 if __name__ == '__main__': db.create_all() create_example_data() app.run(debug=True) 

Patterns

in macros.html

 {% macro render_field(field) %} <dt>{{ field.label }} <dd>{{ field(**kwargs)|safe }} {% if field.errors %} <ul class=errors> {% for error in field.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} </dd> {% endmacro %} {% macro render_data(field) %} <dt>{{ field.label }} <dd>{{ field.data|safe }} {% if field.errors %} <ul class=errors> {% for error in field.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} </dd> {% endmacro %} 

In registration.html

 {% from "macros.html" import render_field %} <form method=post action="/"> {{registration_form.hidden_tag()}} <dl> {{ render_field(registration_form.first_name_field) }} {{ render_field(registration_form.last_name_field) }} {{ render_field(registration_form.address_line_one_field) }} {{ render_field(registration_form.address_line_two_field) }} {{ render_field(registration_form.city_field) }} {{ render_field(registration_form.state_select_field) }} {{ render_field(registration_form.country_select_field) }} </dl> <p><input type=submit value=Register> </form> 

Finally, in success.html

 {% from "macros.html" import render_data %} <h1> This data was saved to the database! </h1> <form method=post action="/"> {{registration_form.hidden_tag()}} <dl> {{ render_data(registration_form.first_name_field) }} {{ render_data(registration_form.last_name_field) }} {{ render_data(registration_form.address_line_one_field) }} {{ render_data(registration_form.address_line_two_field) }} {{ render_data(registration_form.city_field) }} {{ render_data(registration_form.state_select_field) }} {{ render_data(registration_form.country_select_field) }} </dl> <p><input type=submit value=Register> </form> 
+10
source share

All Articles