I am trying to autopopulate data from my Flask-SQLAlchemy database to a FlaskForm. Here are my code snippets:
我正在尝试将数据从我的FlaskSQLAlChemy数据库自动填充到FlaskForm。以下是我的代码片段:
class Products(db.Model):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(100), nullable=False, unique=True)
cost = db.Column(db.Float(), nullable=False)
price = db.Column(db.Float(), nullable=False)
category = db.Column(db.String(20), nullable=False)
details = db.Column(db.String(255), nullable=True)
quantity = db.Column(db.Integer(), nullable=False, default=0)
threshold = db.Column(db.Integer(), nullable=False, default=0)
prod_img = db.Column(db.String(20), nullable=False, default='prod_img.jpg')
disc_amt = db.Column(db.Float(), nullable=True)
disc_percent = db.Column(db.Float(), nullable=True)
disc_conditions = db.Column(db.String(255), nullable=True)
promo_start = db.Column(db.DateTime(), nullable=True)
promo_end = db.Column(db.DateTime(), nullable=True)
def __repr__(self):
return f"Products('{self.name}', '{self.price}', '{self.quantity}')"
I want to autopopulate the products from this model to a form that takes in purchases. Here are my forms:
我想把这种型号的产品自动填充到一种可以接受购买的形式。以下是我的表格:
from flask_wtf import FlaskForm
from wtforms import SubmitField, FloatField, IntegerField, FieldList, FormField, DateField
from wtforms.validators import DataRequired
from wtforms_sqlalchemy.fields import QuerySelectField
from root.models import Products, Suppliers
class ProductForm(FlaskForm):
name = QuerySelectField('Product Name', validators=[DataRequired()], query_factory=lambda: Products.query.all(), get_label='name')
quantity = IntegerField('Quantity', validators=[DataRequired()])
total = FloatField('Total Cost', validators=[DataRequired()])
submit = SubmitField('Add Product')
class ReceiptForm(FlaskForm):
date = DateField('Date', validators=[DataRequired()])
supplier = QuerySelectField('Supplier', validators=[DataRequired()], query_factory=lambda: Suppliers.query.all(), get_label='company')
products = FieldList(FormField(ProductForm), min_entries=1)
submit = SubmitField('Add Purchase')
And here is my route:
这是我的路线:
from flask import Blueprint, render_template
from root.models import Products
from root.purchases.forms import ReceiptForm
purchases = Blueprint('purchases', __name__)
@purchases.route('/add_receipt/', methods=['GET', 'POST'])
def add_receipt():
form = ReceiptForm()
print(type(form.products[0].name)) # Print the type of the 'name' field
print(form.products[0].name) # Print the 'name' field itself
if form.validate_on_submit():
pass
return render_template('add_purchases.html', form=form)
And finally a snippet of my template:
最后是我的模板的一小段:
<div class="card">
<div class="card-header"><h2 class="lead">Add Purchases</h2></div>
<div class="card-body">
<form action="" id="purchase-form">
{{ form.hidden_tag() }}
<div class="mb-3">
{{ form.date.label }} {{ form.date(class="form-control") }}
</div>
<div class="mb-3">
{{ form.supplier.label }} {{ form.supplier(class="form-control") }}
</div>
{% for product_form in form.products %}
<div class="mb-3">
{{ product_form.name.label }} {{ product_form.name(class="form-control") }}
{{ product_form.quantity.label }} {{ product_form.quantity(class="form-control") }}
{{ product_form.total.label }} {{ product_form.total(class="form-control") }}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
When I run this code, I keep getting the error below:
当我运行这段代码时,我一直收到以下错误:
127.0.0.1 - - [09/Sep/2023 16:24:36] "GET /add_receipt/ HTTP/1.1" 500 -
Traceback (most recent call last):
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\flask\app.py", line 2213, in __call__
return self.wsgi_app(environ, start_response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\flask\app.py", line 2193, in wsgi_app
response = self.handle_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\flask\app.py", line 2190, in wsgi_app
response = self.full_dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\flask\app.py", line 1486, in full_dispatch_request
rv = self.handle_user_exception(e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\flask\app.py", line 1484, in full_dispatch_request
rv = self.dispatch_request()
^^^^^^^^^^^^^^^^^^^^^^^
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\flask\app.py", line 1469, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "x:\Code\a-FLASK\Projects\retail_pos\root\purchases\routes.py", line 16, in add_receipt
return render_template('add_purchases.html', form=form)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\flask\templating.py", line 151, in render_template
return _render(app, template, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\flask\templating.py", line 132, in _render
rv = template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\jinja2\environment.py", line 1301, in render
self.environment.handle_exception()
File "X:\Code\a-FLASK\Projects\retail_pos\virt\Lib\site-packages\jinja2\environment.py", line 936, in handle_exception
raise rewrite_traceback_stack(source=source)
File "x:\Code\a-FLASK\Projects\retail_pos\root\templates\add_purchases.html", line 1, in top-level template code
{% extends 'base.html' %}
File "x:\Code\a-FLASK\Projects\retail_pos\root\templates\base.html", line 162, in top-level template code
{% block content %}{% endblock content %}
File "x:\Code\a-FLASK\Projects\retail_pos\root\templates\add_purchases.html", line 30, in block 'content'
{{ product_form.name.label }} {{ product_form.name(class="form-control") }}
TypeError: 'str' object is not callable
127.0.0.1 - - [09/Sep/2023 16:24:36] "GET /add_receipt/?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 304 -
127.0.0.1 - - [09/Sep/2023 16:24:36] "GET /add_receipt/?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 304 -
127.0.0.1 - - [09/Sep/2023 16:24:36] "GET /add_receipt/?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 304 -
127.0.0.1 - - [09/Sep/2023 16:24:37] "GET /add_receipt/?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 304 -
Can someone please tell me where I went wrong?
谁能告诉我我哪里搞错了?
I tried working with the coerce function as well but that bore me another whole mountain of errors.
我也尝试过使用强制函数,但这让我又犯了一大堆错误。
更多回答
The error is occurring because product_form.name
is a string, not a QuerySelectField
as you intended.
出现该错误是因为product_form.name是一个字符串,而不是您想要的QuerySelectField。
For debugging purposes, you can print form.products[0].name
before rendering the template to inspect what it contains. It should be a field object, not a string
.
出于调试目的,可以在呈现模板之前打印Form.Products[0].name以检查其包含的内容。它应该是一个字段对象,而不是字符串。
更多回答
I checked and it displays that it is indeed a string yet I set it as a QuerySelectField in my code. I don't understand why it does not recognize the code
我检查了一下,它显示它确实是一个字符串,但我在代码中将其设置为QuerySelectField。我不明白为什么它不能识别代码
wtforms alone product_form.name is shorthand for product_form.form.name. However, that syntax seems to clash with Jinja, and there it is necessary to use the explicit product_form.form.name in the template.)
WtForms单独的product_form.name是product_form.form.name的缩写。然而,该语法似乎与JJJA冲突,因此有必要在模板中使用显式的product_form.form.name。)
Please also like and accept, if my answer helps you :)
如果我的回答对您有帮助,也请点赞并接受:)
Does that mean I should change the name variable in wtforms? l
这是否意味着我应该更改wtForms中的名称变量?L
Like instead of name maybe call it product_name, is that what you mean?
比如,你可以把它叫做product_name,而不是名字,你是这个意思吗?
我是一名优秀的程序员,十分优秀!