AttributeError: 'Request' object has no attribute 'post'

Question:

I have been working on implementing WTForms Dynamic Fields. Linked: https://pypi.org/project/WTForms-Dynamic-Fields/

I am getting the error: AttributeError: 'Request' object has no attribute 'post'

I understand I am doing something wrong, but I am not entirely sure what, exactly.

My code is:

@app.route("/create", methods=["POST", "GET"])
@login_required
def create():
    if request.method == "POST":
        name = request.form.get('name')
        phone = request.form.get('phone')
        email = request.form.get('email')
        company = request.form.get('company')
        frequency = request.form.get('frequency')
        datefc = datetime.strptime(request.form.get('date'), "%Y-%m-%d")
        adate = datetime.today()

        if frequency == "Weekly":
            nContactTime = datefc + timedelta(days=7)
        elif frequency == "Monthly":
            nContactTime = datefc + timedelta(days=30)
        elif frequency == "Quarterly":
            nContactTime = datefc + timedelta(days=90)

        people.insert_one({"name": name, "phone": phone, "email": email, "company": company, "frequency": frequency,
                           "parentrecord": current_user.user_json['_id'], "dateadded": adate.strftime("%x"),
                           "datefc": datefc, "nextContact": nContactTime})

        flash('Your record has been entered successfully.')
        return redirect(url_for('profile'))
    elif request.method == "GET":
        cfv = customfields.find({"_id": current_user.user_json['_id']})

        dynamic = WTFormsDynamicFields()


        for value in cfv:
            print(value['fieldName'] + value['fieldType'])
            if value['fieldType'] == "Text Field":
                dynamic.add_field(value['fieldName'], value['fieldName'], StringField)

        form = dynamic.process(CreateRecord, request.post)

        return render_template('create.html', form=form, auth=current_user.is_authenticated)

My form class is:

class CreateRecord(FlaskForm):
    name = StringField('Name', validators=[DataRequired()])
    phone = StringField('Phone')
    email = StringField('Email')
    company = StringField('Company', validators=[DataRequired()])
    frequency = SelectField('Follow-up Frequency',
                            choices=[('Weekly', 'Weekly'), ('Monthly', 'Monthly'), ('Quarterly', 'Quarterly')])
    date = DateField('First Date To Contact', validators=[DataRequired()])
    submit = SubmitField('Create Record')

My goal is to simply have the new fields show up on the rendered page which for testing purposes I have kept the code simple at:

{% for field in form %}
    {{ field() }}
{% endfor %}
Asked By: David

||

Answers:

In order to register new fields, you must pass a dictionary containing the fields you’ll like to pick out from your WTFormsDynamicFields object to be available in your form.

For example, if one wants to add an email field dynamically that is required.
One must provide a MutableDict that includes the email field.

templates/index.html

{% for field in form %}
    {{ field.label }} {{ field() }}
{% endfor %}

app.py

from flask import Flask, request, render_template
from wtforms import Form, TextField
from wtforms.validators import InputRequired
from wtforms_dynamic_fields import WTFormsDynamicFields
from werkzeug.datastructures import ImmutableMultiDict

app = Flask(__name__)

class PersonalFile(Form):
    """ A personal file form. """
    first_name = TextField('First name', validators=[InputRequired()])
    last_name = TextField('Last name', validators=[InputRequired()])


class Dict: 
    '''Wrapper klass because iteritems no longer available in Python3.7 dict'''
    def __init__(self, mapping):
        self.mapping = ImmutableMultiDict(mapping)

    def iteritems(self):
        return self.mapping.items()
    
    def __getattr__(self, attr):
        return getattr(self.mapping, attr) 
    
    def __iter__(self):
        return dict.__iter__(self.mapping)


@app.route('/', methods=['GET', 'POST'])
def index():
    dynamic = WTFormsDynamicFields()
    dynamic.add_field('email', 'Email address', TextField)
    dynamic.add_validator('email', InputRequired, message='This field is required')
    dynamic.add_field('subject', 'Subject', TextField)
    post = request.form.copy() # making a mutable dict copy

    # add email in post mapping to declare 
    # that we are going to want this field in the form
    post.add('email', '')
    post = Dict(post) # Wrapping the mutable dict as immutable
    # augumenting form with email field. 
    # Note that if we want to show the subject field,
    # we must add the 'subject' key in the post mapping.
    form = dynamic.process(PersonalFile, post)  
    if request.method == "POST":
        return request.form

    if request.method == 'GET':
        return render_template('index.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)
Answered By: Oluwafemi Sule
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.