Я хотел бы предварить это, заявив, что английский не является моим родным языком, если какие-либо из моих объяснений расплывчаты или не имеют смысла, сообщите мне, и я постараюсь сделать их более ясными.
У меня проблема с заполнением SelectMultipleField
правильными данными в Flask-WTF. Как видно из приведенного ниже кода, я передаю объект пользователя в форму. Это работает безупречно, так как заполняет все поля при отображении страницы. Проблема, с которой я сталкиваюсь, заключается в том, что SelectMultipleField
заполняется идентификаторами ролей, а не именами ролей.
В разделе форм я создаю список choices
, содержащий все доступные варианты, которые должны отображаться. Я могу преобразовать это в choices.append((role.id, role.name))
, и оно заполнит поле именами вместо идентификаторов. Однако, если я это сделаю, роли, назначенные пользовательскому объекту (из базы данных), не будут отображаться как предварительно выбранные.
Как я могу сделать так, чтобы поле предварительно заполнялось именами, а не идентификаторами, и сохраняло предварительно выбранные назначенные роли?
Любое руководство или толчок в правильном направлении будет принят с благодарностью. Если не хватает какой-либо информации, которую я не догадался добавить, дайте мне знать, и я ее добавлю.
# Models
class Role(db.Document, RoleMixin):
meta = {'collection': 'role'}
name = db.StringField(max_length=80, unique=True)
description = db.StringField(max_length=255)
def __repr__(self):
return '<Role {}>'.format(self.name)
def __str__(self):
return self.name
class User(db.Document, UserMixin):
meta = {'collection': 'User'}
first_name = db.StringField(max_length=30)
last_name = db.StringField(max_length=30)
email = db.StringField(max_length=120)
password_hash = db.StringField(max_length=255)
active = db.BooleanField(default=True)
roles = db.ListField(db.ReferenceField(Role), default=[])
def __repr__(self):
return '<User {}>'.format(self.email)
def __str__(self):
return self.email
# Forms
class EditUserForm(FlaskForm):
choices = []
for role in Role.objects:
choices.append((role.name, role.id))
first_name = StringField('First name', validators=[DataRequired()])
last_name = StringField('Last name', validators=[DataRequired()])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password')
password2 = PasswordField('Repeat password', validators=[EqualTo('password')])
roles = SelectMultipleField('User roles', choices=choices)
submit = SubmitField('Save')
# Routes
@app.route('/users/edit/<id>', methods=['GET', 'POST'])
@roles_required('admin')
def edit_user(id):
user = User.objects(id=id).first()
form = EditUserForm(obj=user)
if form.validate_on_submit() and request.method == 'POST':
user.first_name=form.first_name.data
user.last_name=form.last_name.data
user.email=form.email.data
user.roles = []
for role in form.roles.data:
r = Role.objects(name=role).first()
user.set_role(r.id)
if form.password.data:
user.set_password(form.password.data)
user.save()
return redirect(url_for('users'))
return render_template('edit_user.html', title='Edit user', user=user, form=form)
Шаблон:
{% extends "layout.html" %}
{% set active_page = "edit_user" %}
{% block jumbotron %}
<h1>{{ title }}</h1>
<form action="" method="post">
{{ form.hidden_tag() }}
<p>
{{ form.first_name.label }}<br>
{{ form.first_name(size=32) }}<br>
{% for error in form.first_name.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.last_name.label }}<br>
{{ form.last_name(size=32) }}<br>
{% for error in form.last_name.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.email.label }}<br>
{{ form.email(size=32) }}<br>
{% for error in form.email.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=32) }}<br>
{% for error in form.password.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.password2.label }}<br>
{{ form.password2(size=32) }}<br>
{% for error in form.password2.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.roles.label }}<br>
{{ form.roles(size=32) }}<br>
{% for error in form.roles.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>{{ form.submit() }}</p>
</form>
{% endblock %}
Я попытался создать свой собственный объект с кодом ниже, чтобы перейти к форме, однако мне это не удалось. При передаче этого объекта в форму поля не заполнялись.
user = User.objects(id=id).first()
temps = []
u = user.to_mongo()
u['_id'] = {'$oid': str(u['_id'])}
temp_roles = []
for role in user.roles:
r = role.to_mongo()
r['_id'] = {'$oid': str(r['_id'])}
temp_roles.append(r)
u['roles'] = temp_roles
choices.append((role.name, role.name))
? - person PRMoureu   schedule 08.07.2018