ProgramingTip

사용하여 단일 페이지에 여러 양식을 사용하여

bestdevel 2020. 12. 15. 19:38
반응형

사용하여 단일 페이지에 여러 양식을 사용하여


다수의 양식이 있습니다.

나는 양식을 사용하여 양식을 생성하고 있습니다.

최초의 양식을 생성하는 가장 좋은 방법은 무엇입니까?

나는 현재 action="?form=oneform". 더 나은 방법이 생각합니다.


나는 두 개의 사용 가능한 스 니펫의 조합을 사용하고 있습니다. 첫 번째는 양식에 접두사를 추가 한 다음 validate_on_submit ()을 사용하여 접두사를 확인합니다. 또한 Louis Roché의 템플릿을 사용하여 양식에서 어떤 버튼을 눌렀는지 확인합니다 .

Dan Jacob을 인용 광고 :

예 :

form1 = FormA(prefix="form1")
form2 = FormB(prefix="form2")
form3 = FormC(prefix="form3")

그런 다음 숨겨진 필드를 추가하거나 필드를 확인하십시오.

if form1.validate_on_submit() and form1.submit.data:

Louis Roché의 인용문 :

내 템플릿에 있습니다.

<input type="submit" name="btn" value="Save">
<input type="submit" name="btn" value="Cancel">

그리고 어떤 버튼이 서버 측에 전달되어 어떤 알아 내기 위해 내 views.py 파일에 있습니다.

if request.form['btn'] == 'Save':
    something0
else:
    something1

위의 솔루션에는 유효성 검사가 있습니다. 한 양식에서 유효성 검사 오류가 발생하면 두 양식 모두 오류 메시지가 표시됩니다. if이 문제를 해결 하기 위해 순서를 변경합니다 .

먼저 다음 SubmitField과 같이 다른 이름으로 다중 정의하십시오 .

class Form1(Form):
    name = StringField('name')
    submit1 = SubmitField('submit')

class Form2(Form):
    name = StringField('name')
    submit2 = SubmitField('submit')

....

그런 다음 다음에 필터를 추가하십시오 view.py.

....
form1 = Form1()
form2 = Form2()
....

if form1.submit1.data and form1.validate(): # notice the order 
....
if form2.submit2.data and form2.validate(): # notice the order 
....

이제 문제가 해결되었습니다.

계속 진행 되세요.

여기 있습니다 validate_on_submit():

def validate_on_submit(self):
    """
    Checks if form has been submitted and if so runs validate. This is
    a shortcut, equivalent to ``form.is_submitted() and form.validate()``
    """
    return self.is_submitted() and self.validate()

그리고 여기 있습니다 is_submitted():

def is_submitted():
    """Consider the form submitted if there is an active request and
    the method is ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
    """
    return _is_submitted()  # bool(request) and request.method in SUBMIT_METHODS

호출하면을 form.validate_on_submit()어떤 제출 버튼을 클릭했는지에 관계없이 HTTP 메서드에 의해 양식이 제출되었는지 확인 합니다 . 따라서 위의 작은 트릭은 필터를 추가하는 것입니다 (제출에 데이터가 있는지 확인하기 위해, 즉 form1.submit1.data).

또한 순서를 변경하여 if호출 하나를 클릭 하면 양식 만 호출 validate()하여 두 양식에 대한 유효성 검사를 방지합니다.

이야기는 아직 끝나지 가능성이 있습니다. 여기 있습니다 .data:

@property
def data(self):
    return dict((name, f.data) for name, f in iteritems(self._fields))

필드 이름 (키)과 필드 데이터 (값)가있는 dict를 반환하지만 두 양식 제출 버튼은 이름 submit(키)을 갖습니다 !

첫 번째 첫 번째 버튼 버튼을 클릭하면 form1.submit1.data다음과 같은 dict 반환합니다.

temp = {'submit': True}

우리가 전화를 의심의 여지가있다 if form1.submit.data:, 그것은 반환은 True.

우리가 (형식 2에서) 두 번째 버튼 버튼을 클릭하면, 호출 .data에서이 if form1.submit.data:딕셔너리의 키-값을 추가 첫째 로, 다음 전화를 if form2.submit.data:결국, DICT이 같은 것, 다른 키-값을 추가 :

temp = {'submit': False, 'submit': True}

이제 우리 가 클릭 한 번 호출 버튼이 form2에 있더라도 호출 if form1.submit.data:하면 반환 True됩니다.

이것이 우리 가이 둘 SubmitField을 다른 이름으로 정의해야하는 이유 입니다. (여기까지)!

최신 정보

한 페이지에서 여러 양식을 처리하는 또 다른 방법이 있습니다. 여러보기사용 하여 양식을 처리 할 수 있습니다 . 예를 들면 :

...
@app.route('/')
def index():
    register_form = RegisterForm()
    login_form = LoginForm()
    return render_template('index.html', register_form=register_form, login_form=login_form)

@app.route('/register', methods=['POST'])
def register():
    register_form = RegisterForm()
    login_form = LoginForm()

    if register_form.validate_on_submit():
        ...  # handle the register form
    # render the same template to pass the error message
    # or pass `form.errors` with `flash()` or `session` then redirect to /
    return render_template('index.html', register_form=register_form, login_form=login_form)


@app.route('/login', methods=['POST'])
def login():
    register_form = RegisterForm()
    login_form = LoginForm()

    if login_form.validate_on_submit():
        ...  # handle the login form
    # render the same template to pass the error message
    # or pass `form.errors` with `flash()` or `session` then redirect to /
    return render_template('index.html', register_form=register_form, login_form=login_form)

템플릿 (index.html)에서 두 양식을 모두 사용하고 action속성을 대상보기로 설정해야 합니다.

<h1>Register</h1>
<form action="{{ url_for('register') }}" method="post">
    {{ register_form.username }}
    {{ register_form.password }}
    {{ register_form.email }}
</form>

<h1>Login</h1>
<form action="{{ url_for('login') }}" method="post">
    {{ login_form.username }}
    {{ login_form.password }}
</form>

간단한 방법은 필드마다 다른 이름을 사용하는 것입니다. 예를 들어 :

forms.py :

class Login(Form):

    ...
    login = SubmitField('Login')


class Register(Form):

    ...
    register = SubmitField('Register')

views.py :

@main.route('/')
def index():

    login_form = Login()
    register_form = Register()


    if login_form.validate_on_submit() and login_form.login.data:
        print "Login form is submitted"

    elif register_form.validate_on_submit() and register_form.register.data:
        print "Register form is submitted"

    ...

다른 답변과 같이 페이지의 각 양식에 대해 각 요청 버튼에 고유 한 이름을 할당합니다.

그런 다음 다음 웹 작업은 입니다. 그에 따라 양식 필드 초기화 / 유지 하는 데 도움이되는 것 formdataobj변수를 확인 합니다 .

@bp.route('/do-stuff', methods=['GET', 'POST'])
def do_stuff():
    result = None

    form_1 = None
    form_2 = None
    form_3 = None

    if "submit_1" in request.form:
        form_1 = Form1()
        result = do_1(form_1)
    elif "submit_2" in request.form:
        form_2 = Form2()
        result = do_2(form_2)
    elif "submit_3" in request.form:
        form_3 = Form3()
        result = do_3(form_3)

    if result is not None:
        return result

    # Pre-populate not submitted forms with default data.
    # For the submitted form, leave the fields as they were.

    if form_1 is None:
        form_1 = Form1(formdata=None, obj=...)
    if form_2 is None:
        form_2 = Form2(formdata=None, obj=...)
    if form_3 is None:
        form_3 = Form3(formdata=None, obj=...)

    return render_template("page.html", f1=form_1, f2=form_2, f3=form_3)


def do_1(form):
    if form.validate_on_submit():
        flash("Success 1")
        return redirect(url_for(".do-stuff"))


def do_1(form):
    if form.validate_on_submit():
        flash("Success 2")
        return redirect(url_for(".do-stuff"))

def do_3(form):
    if form.validate_on_submit():
        flash("Success 3")
        return redirect(url_for(".do-stuff"))

예 : 단일 HTML 페이지의 여러 WTForm

app.py

"""
Purpose Create multiple form on single html page.

Here we are having tow forms first is Employee_Info and CompanyDetails
"""
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField, FloatField, validators
from wtforms.validators import InputRequired

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

class EmployeeInfo(FlaskForm):
    """
    EmployeeInfo class will have Name,Dept
    """
    fullName = StringField('Full Name',[validators.InputRequired()])
    dept = StringField('Department',[validators.InputRequired()])

class CompanyDetails(FlaskForm):
    """
    CompanyDetails will have yearOfExp. 
    """
    yearsOfExp = IntegerField('Year of Experiece',[validators.InputRequired()]) 


@app.route('/', methods = ['GET','POST'] )
def index():
    """
    View will render index.html page.
    If form is validated then showData.html will load the employee or company data.
    """
    companydetails = CompanyDetails()
    employeeInfo = EmployeeInfo()

    if companydetails.validate_on_submit():
        return render_template('showData.html', form = companydetails)

    if employeeInfo.validate_on_submit():
        return render_template('showData.html', form1 = employeeInfo)   

    return render_template('index.html',form1 = employeeInfo, form = companydetails)

if __name__ == '__main__':
    app.run(debug= True, port =8092)

템플릿 / index.html

<html>
    <head>
    </head>
    <body>  
        <h4> Company Details </h4>

        <form method="POST" action="{{url_for('index')}}">

            {{ form.csrf_token }}

            {{ form.yearsOfExp.label }} {{ form.yearsOfExp }}       

            <input type="submit" value="Submit">
        </form>

        <hr>
        <h4> Employee Form </h4>

        <form method="POST" action="{{url_for('index')}}" >

            {{ form1.csrf_token }}

            {{ form1.fullName.label }} {{ form1.fullName }}

            {{ form1.dept.label }} {{ form1.dept }}

            <input type="submit" value="Submit">
        </form>
    </body>
</html>

showData.html

<html>
    <head> 
    </head> 
    <body>
        {% if form1 %}
        <h2> Employee Details </h2>
            {{ form1.fullName.data }}
            {{ form1.dept.data }}
        {% endif %}
        {% if form %}
            <h2> Company Details </h2>
                {{ form.yearsOfExp.data }}      
        {% endif %}     
    </body>
</html>

I haven't used WTForms but should work regardless. This is a very quick and simple answer; all you need to do is use different values for the submit button. You can then just do a different def based on each. 

in index.html: 

    <div>
        <form action="{{ url_for('do_stuff')}}" method="POST">
            <h1>Plus</h1>
            <input type = "number" id = "add_num1" name = "add_num1" required><label>Number 1</label><br>
            <input type = "number" id = "add_num2" name = "add_num2" required><label>Number 2</label><br>
            <input type = "submit" value = "submit_add" name = "submit" ><br>
        </form>
        <p>Answer: {{ add }}</p>
    </div>

    <div>
        <form action="{{ url_for('do_stuff')}}" method="POST">
            <h1>Minus</h1>
            <input type = "number" id = "min_num1" name = "min_num1" required><label>Number 1</label><br>
            <input type = "number" id = "min_num2" name = "min_num2" required><label>Number 2</label><br>
            <input type = "submit" value = "submit_min" name = "submit"><br>
        </form>
        <p>Answer: {{ minus }}</p>
    </div>

in app.py:

@app.route('/',methods=["POST"])
def do_stuff():
    if request.method == 'POST':
        add = ""
        minus = ""
        if request.form['submit'] == 'submit_add':
            num1 = request.form['add_num1']
            num2 = request.form['add_num2']
            add = int(num1) + int(num2)

        if request.form['submit'] == 'submit_min':
            num1 = request.form['min_num1']
            num2 = request.form['min_num2']
            minus = int(num1) - int(num2)
    return render_template('index.html', add = add, minus = minus)

참조 URL : https://stackoverflow.com/questions/18290142/multiple-forms-in-a-single-page-using-flask-and-wtforms

반응형