酷炫網站模板抖音seo供應商
背景:
在flask-admin 的modelview視圖下實現(xiàn)自定義視圖的表單修改/編輯是件不太那么容易的事情,特別是想不自定義前端view的情況下。
材料:
wtforms+flask_sqlalchemy
制作:
上代碼
1、模型代碼
from .exts import db
from flask_login import UserMixin
from datetime import datetimeclass AiConfig(db.Model, UserMixin):__tablename__ = 'ai_config'id = db.Column(db.Integer, primary_key=True, autoincrement=True)created_at = db.Column(db.TIMESTAMP, default=datetime.utcnow)updated_at = db.Column(db.TIMESTAMP, default=datetime.utcnow)status = db.Column(db.Integer)ai_name = db.Column(db.String(128))
注:默認日期函數可以采用?default=datetime.utcnow 來實現(xiàn)
2、視圖測代碼
a、AiConfigForm 表單
class AiConfigForm(form.Form):def get_countries():return Organ.query.order_by('updated_at').all()ai_name = fields.StringField('AI名稱', validators=[validators.DataRequired()])ai_code = fields.StringField('AI編號', validators=[validators.DataRequired()])ai_extends = fields.TextAreaField('配置擴展', widget=TextArea())root_url = fields.URLField('根URL', validators=[validators.DataRequired()], widget=URLInput())organ = QuerySelectField('機構名稱', validators=[validators.DataRequired()], query_factory=get_countries, get_label='org_name') description = fields.TextAreaField('描述', widget=TextArea())status = fields.SelectField('狀態(tài)', choices=[(1, '有效'), (0, '無效')], default=0)
b、modeview視圖下實現(xiàn)表單新增
@expose('/new/', methods=('GET', 'POST'))def create_view(self):bean = AiConfig()bean.updated_at = datetime.today()form = AiConfigForm(request.form, obj=bean)if self.validate_form(form):model = self.create_model(form)if model:flash(gettext('Record was successfully created.'), 'success')return redirect(self.get_save_return_url(model, is_created=True))if self.create_modal and request.args.get('modal'):template = self.create_modal_templateelse:template = self.create_templatereturn self.render(template, form=form)
注:上面代碼片段中這樣修改update_at 是不生效的,目前尚未找到在這個代碼交互中修改表單AiConfigForm 中并未定義字段update_at 屬性的方法 (因為屬性賦值是在其self.create_model()內置函數中實現(xiàn)的)
c、modelview 視圖下實現(xiàn)表單修改
@expose('/edit/', methods=('GET', 'POST'))def edit_view(self):id = request.args['id']return_url = request.values.get('url') or self.get_url('.index_view')model = self.get_one(id)if model is None:flash(gettext('Record does not exist.'), 'error')return redirect(return_url)form = AiConfigForm(request.form, obj=model)if self.validate_form(form):model.updated_at = datetime.today()if self.update_model(form, model):flash(gettext('Record was successfully saved.'), 'success')# save buttonreturn redirect(self.get_save_return_url(model, is_created=False)) if request.method == 'GET' or form.errors:self.on_form_prefill(form, id)if self.edit_modal and request.args.get('modal'):template = self.edit_modal_templateelse:template = self.edit_templatereturn self.render(template, form=form)
注:上述代碼片段中 model.updated_at = datetime.today() 是有效的,因為在self.update_model(form,model) 內置函數中只是將form 中表單數據通過?form.populate_obj(model) 值cp 的方式簡單覆蓋來實現(xiàn),我們只需要在調用該方法前將model 進行修改便可生效。
效果?
1、編輯/新增 view中不存在日期2?
?
2、數據庫中存在日期
3、列表中該記錄存在日期
?
注:這就充分說明通過上述邏輯實現(xiàn)了新增日期和修改日期的后臺修改
疑問與經驗?
疑問
1、為啥不在AiConfigForm 表單中通過影藏字段來實現(xiàn)日期呢?
該方案有嘗試,但是不行,因為數據庫屬性是日期類型的,實體中該字段也是日期類型,如果只是在表單中采用影藏字段,新增時非常好用,只需要通過form.updated_at.data=datetime.today()實現(xiàn)賦值,但編輯時就會因為模型字段與表單中針對updated_at 字段的類型定義不一致導致無法通過populate_obj 函數進行模型值賦值導致報異常,同時由于此刻表單中并沒有updated_at這樣的日期類型字段,有的只是影藏字段,故無法form.updated_at.data=datetime.today() 實現(xiàn)賦值。當然如果不怕麻煩可以寫2個form 視圖就可以友好結果上述問題。
2、為啥不直接自定義view模板呢?
當然可以,只是因為懶。
3、為啥不建2個AiConfigForm 視圖,一個用于編輯一個用于新增?
當然可以,而且可以做到很優(yōu)雅,只是懶
經驗
1、在ModelView 的子視圖中重寫部分方法,如@expose('/new/', methods=('GET', 'POST'))和@expose('/edit/', methods=('GET', 'POST')),中如果采用wtforms 自定義表單,但又不想自定義表單視圖,那么只需要簡單的通過form = AiConfigForm(request.form, obj=bean) 方法在上面新增、編輯函數中使用wtforms 表單。但這里要說明的是AiConfigForm(request.form, obj=bean) 中的 obj 對象接收的是模型,通過把模型賦值給obj 的方式實現(xiàn)已有數據的回填,該方案在編輯中非常有用
?
?
?
?