Как отобразить поле внешнего ключа flask в форме модели с читаемым раскрывающимся списком? - PullRequest
0 голосов
/ 29 января 2020

У меня есть отношения один ко многим и многие ко многим в моих моделях. Я использую wtforms_alchemy ModelForm для создания форм, но поле ForeignKey не отображается как раскрывающееся поле, а также целые числа в качестве значений в них. Я пытался ссылаться на похожие вопросы и пробовал ответы, например, я добавил в них функции __str__(), а также __repr__(), чтобы они возвращали в раскрывающемся списке некоторую читаемую и значимую строку, но этого не произошло. Кто-нибудь знает, как еще я могу это сделать?

enter image description here

Models.py-


class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), nullable=False)
    location_id = db.Column(db.Integer, db.ForeignKey('location.id'))

    def __init__(self, name, location=None):
        self.name = name
        if location:
            self.location_id = location.id

    def __repr__(self):
        warehouse = Location.query.filter_by(id = self.location_id).first()
        qty = warehouse.get_product_quantity(self.name)
        return '{0}-{1}-{2}'.format(self.name, warehouse.name, qty)

class Location(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), unique=True, nullable=False)
    products = db.relationship('Product', backref='warehouse')

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return 'Location-{0}'.format(self.name)

class Movement(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    from_location_id = db.Column(db.Integer, db.ForeignKey("location.id"))
    to_location_id = db.Column(db.Integer, db.ForeignKey("location.id"))
    from_location = db.relationship(Location, lazy='joined', foreign_keys=[from_location_id], backref='from_location')
    to_location = db.relationship(Location, lazy='joined', foreign_keys=[to_location_id], backref='to_location')
    product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
    product = db.relationship(Product, backref='movements')
    qty = db.Column(db.Integer)

forms.py -

class ProductForm(ModelForm, Form):
    class Meta:
        model = Product
        include = ['name']

class LocationForm(ModelForm, Form):
    class Meta:
        model = Location
        include = ['name']

class MovementForm(ModelForm, Form):
    class Meta:
        model = Movement
        include = ['from_location_id', 'to_location_id', 'product_id', 'qty']

1 Ответ

0 голосов
/ 29 января 2020

Поскольку идентификаторы являются целыми числами, WTForm-ALchemy преобразует поле формы в целочисленное поле, вы можете увидеть это здесь

Таким образом, вы можете принудительно использовать поле выбора, как объяснено здесь

Если вы хотите больше читабельности, вы можете использовать QuerySelectField .

class MovementForm(ModelForm, Form):
    class Meta:
        model = Movement

    product = QuerySelectField(
        query_factory=lambda: Product.query.all(),
        get_pk=lambda a: a.id,
        get_label=lambda a: a.name,
        allow_blank=False,
    )

Если вы предпочитаете, вы можете использовать вид / маршрут запросить и передать в форму параметры.

def movement_new():
    movement = Movement()
    form = MovementForm(obj=movement)

    products = [(c.id, c.name) for c in Product.query.all()]
    form.product_id.choices = products
    ...

Затем на MovementForm

class MovementForm(ModelForm, Form):
    class Meta:
        model = Movement    ---> note tha the include was removed

    product_id = SelectField('Product', coerce=int)
  ...
...