【问题标题】:SQLAlchemy how do I update only certain fields of my recordSQLAlchemy 如何仅更新记录的某些字段
【发布时间】:2020-07-24 03:28:09
【问题描述】:

我有一个模型(公司),其中包含一些字段。创建公司记录后,我希望能够从表单更新此记录。但是,如果其中一个字段为空白,那么我想忽略该字段并保留当前信息。

我尝试创建一个form.py,然后在我的views.py 中从有效的表单中获取数据。但是,当我尝试提交数据时,出现错误:

AttributeError: 'scoped_session' 对象没有属性 'update'

我已经用谷歌搜索了这个,但我不知道为什么它不会更新。我已经搜索了过去一个小时左右,任何方向都会很棒。谢谢。

Models.py

class Company(db.Model, UserMixin):

    __tablename__ = 'company'

    id = db.Column(db.Integer, primary_key=True)
    # The email is what connects Company and POC (Buyer)
    email = db.Column(db.String(64), unique=True, index=True, nullable=False)
    company = db.Column(db.String(64), index=True, nullable=False)
    company_url = db.Column(db.String(64), index=True, nullable=False)
    # Child relationship to the Event
    duns = db.Column(db.String(11))
    event_id = db.relationship(
        'Events', secondary=event_company, backref='event', lazy='dynamic'
    )
    password_hash = db.Column(db.String(128))
    buyer = db.relationship('Buyers', backref='buyer', lazy='dynamic')

    def __init__(
        self, email, company, duns, company_url,
        password
    ):

Form.py

class UpdateCompanyForm(FlaskForm):
    buyer_id = QuerySelectField(
        'POC Name', query_factory=buyer_query, get_pk=get_pk
    )
    email = StringField('Email', validators=[Email()])
    company = StringField('Company')
    company_url = StringField('Company Website', validators=[URL(message='Must be a valid URL')])
    duns = StringField('DUNS', validators=[DataRequired()])
    password = PasswordField(
        'Password', validators=[EqualTo('pass_confirm',
                                                        message='Passwords must match')]
    )
    pass_confirm = PasswordField('Confirm Password')
    submit = SubmitField('Register!')

Views.py

class UpdateCompanyView(MethodView):

    template_file = 'buyers/update_company.html'
    form_class = UpdateCompanyForm

    def get(self, comp_id):
        # This id will autopopulate the company form as an object
        company_id = Company.query.get(comp_id)
        # Need to join this so I have all buyers associated with the company
        buyer = Buyers.query.filter_by(company=comp_id).first()
        return render_template(
            self.template_file, form=self.form_class(obj=company_id),
            buyer=buyer
        )

    def post(self, comp_id):
        form = self.form_class()

        if form.validate_on_submit():
            buyers_list = form.buyer_id.data.id

            company_info = Company(
                email=form.email.data,
                company=form.company.data,
                company_url=form.company_url.data,
                duns=form.duns.data,
                password=form.password.data
            )
            db.session.update(company_info)
            db.session.commit()

【问题讨论】:

    标签: python-3.x flask flask-sqlalchemy


    【解决方案1】:

    你需要获取你要更新的记录,然后设置属性:

    def post(self, comp_id):
        form = self.form_class()
    
        if form.validate_on_submit():
            buyers_list = form.buyer_id.data.id
    
            company_info = Company.query.get(comp_id)
            company_info.email = form.email.data
            ....
            db.session.commit()
    

    如果您需要忽略空白字段,您可以执行以下操作:

     company_info = Company.query.get(comp_id)
     #Ignore form fields not in data model
     form_data = {i: form.data[i] for i in form.data if i not in ["csrf_token", "submit"]}
     #Remove empty fields
     new_data = {k: v for k, v in form_data.items() if v is not None}
     #Unpack into Company model
     company_info.update(**new_data)
     db.session.commit()
    

    【讨论】:

    • 谢谢你,PGHE。这是有道理的。我遇到了验证器问题。基本上,在我的表格中,我有validators=[URL(message='Must be a valid URL')])。当然,如果我不输入数据,它会捕获此错误。我应该将这个错误捕获到我的 view.py 中吗?
    • 如果是可选字段,您可以添加Optional() 验证器。表单验证本身并不是“捕捉错误”。您应该尝试进行客户端验证,以便用户可以看到他们做错了什么,但您必须进行服务器端验证以保护您的数据库。
    【解决方案2】:

    只需通过查询获取公司对象,在需要的地方更新属性,然后提交会话。

     def post(self, comp_id):
            form = self.form_class()
    
            if form.validate_on_submit():
                buyers_list = form.buyer_id.data.id
                
                company = Company.query.filter_by(id=comp_id)
                
                company.email=form.email.data,
                company.company=form.company.data,
                company.company_url=form.company_url.data,
                company.duns=form.duns.data,
                company.password=form.password.data
                    
                db.session.commit()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2011-11-29
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多