/ / Flask-Admin batch action with form - python, flask, flask-admin

Działanie wsadowe Flask-Admin z formularzem - python, flask, flask-admin

mam Flask aplikacja z Flask-SQLAlchemy i Flask-Admin.

Chciałbym wykonać akcję zbiorczą, ale z formą. Na przykład chciałbym ustawić tę samą wartość tekstową w przypisanym formularzu, ale ta wartość jest wprowadzana przez użytkownika.

widziałem dokumentacja dotycząca działań wsadowych, ale ma przykład tylko dla predefiniowanych danych.

Czy to mo

Odpowiedzi:

2 dla odpowiedzi № 1

Sposób, w jaki to osiągam, polega na wykonaniu wewnętrznego POST w @action metoda.

class AddressView(AdminView):

# ... ....

@action("merge", "Merge", "Are you sure you want to merge selected addresses?")
def action_merge(self, ids):

if len(ids) < 2:
flash("Two or more addresses need to be selected before merging")
return

return_url = request.referrer
return redirect(url_for("mergeaddresses.index", return_url=return_url), code=307)

Następnie zdefiniuj dwie trasy, jedną dla poczty wewnętrznej, a drugą do odbioru POST przesłania z formularza, który odbiera dane wejściowe użytkownika (MergeAddressForm w poniższym przypadku).

W poniższym przykładzie korzystam z plikuFlask-Admin BaseView do obsługi tras. Zwróć uwagę, jak oryginalne, zaznaczone identyfikatory w widoku listy administratora kolby są pobierane, a następnie zapisywane w postaci jako zakodowane pole listy rozdzielonej przecinkami, ukryte pole i podobnie return_url powrót do widoku listy flask-admin.

class MergeAddressesView(BaseView):

form_base_class = BaseForm

def __init__(self, name=None, category=None,
endpoint=None, url=None,
template="admin/index.html",
menu_class_name=None,
menu_icon_type=None,
menu_icon_value=None):
super(MergeAddressesView, self).__init__(name,
category,
endpoint,
url or "/admin",
"static",
menu_class_name=menu_class_name,
menu_icon_type=menu_icon_type,
menu_icon_value=menu_icon_value)
self._template = template

def is_visible(self):
return False

@expose("/", methods=["POST"])
def index(self):
if request.method == "POST":
# get the original checked id"s
ids = request.form.getlist("rowid")

merge_form = MergeAddressForm()
merge_form.process()
joined_ids = ",".join(ids)
encoded = base64.b64encode(joined_ids)
merge_form.ids.data = encoded
_return_url = request.args["return_url"]
merge_form.return_url.data = _return_url
self._template_args["form"] = merge_form
self._template_args["cancel_url"] = _return_url
return self.render(self._template)

@expose("/merge", methods=["POST"])
def merge(self):

if request.method == "POST":
merge_form = MergeAddressForm(selection_choices=[])
decoded = base64.b64decode(merge_form.ids.data)
ids = decoded.split(",")
# do the merging
address_merger = AddressMerger(ids=ids, primary_id=merge_form.primary_address.data)
address_merger.merge()
# return to the original flask-admin list view
return redirect(merge_form.return_url.data)

Mój szablon formularza wejściowego użytkownika wygląda jak poniżej. Zwróć uwagę na adres URL akcji.

{% extends "admin/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block body %}
<h3>{{ admin_view.name|title }}</h3>
<form role="form" action="{{ url_for("mergeaddresses.merge") }}" method="post" name="form">

{{ form.hidden_tag() }}

{{ wtf.form_errors(form) }}

{{ wtf.form_field(form.primary_address) }}

<button type="submit" class="btn btn-primary">Merge</button>
<a href="{{ cancel_url }}" class="btn btn-danger" role="button">Cancel</a>
</form>
{% endblock %}