Skip to content

Commit

Permalink
change model -> drop v_regne + v_group2inpn + tests (#514)
Browse files Browse the repository at this point in the history
Co-authored-by: TheoLechemia <lechemia.theo@gmail.com>

fix (bibattributs) : formatters works with empty liste_valeur_attribut

Detail taxon : afficher les listes

Populate cor_nom_liste : Correction si ligne vide ou champ cd_nom vide

Populate bib_liste: bouton cancel

Black

Add test on populate bib_list (#520)

Co-authored-by: TheoLechemia <lechemia.theo@gmail.com>
  • Loading branch information
2 people authored and amandine-sahl committed Aug 8, 2024
1 parent f56043a commit 355aa68
Show file tree
Hide file tree
Showing 16 changed files with 218 additions and 108 deletions.
69 changes: 26 additions & 43 deletions apptax/admin/admin_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
from flask_admin.model.form import InlineFormAdmin
from flask_admin.model.ajax import AjaxModelLoader, DEFAULT_PAGE_SIZE
from flask_admin.contrib.sqla.filters import FilterEqual

from flask_admin.form.widgets import Select2Widget
from flask_admin.contrib.sqla.fields import QuerySelectField

from flask_admin.base import expose
from flask_admin.model.helpers import get_mdict_item_or_list
Expand All @@ -23,7 +24,7 @@
from flask_admin.model.template import EndpointLinkRowAction, TemplateLinkRowAction
from flask_admin.model.template import EndpointLinkRowAction, TemplateLinkRowAction

from sqlalchemy import or_, inspect, select, func, exists
from sqlalchemy import or_, inspect, select, exists

from sqlalchemy.orm import undefer

Expand All @@ -39,7 +40,6 @@
CorTaxonAttribut,
TMedias,
BibListes,
VMRegne,
cor_nom_liste,
)
from apptax.admin.utils import taxref_media_file_name, get_user_permission
Expand All @@ -55,6 +55,7 @@
FilterMedia,
FilterAttributes,
)
from apptax.admin.mixins import RegneAndGroupFormMixin

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -156,7 +157,7 @@ def can_delete(self):
form_excluded_columns = ["attributs"]


class BibListesView(FlaskAdminProtectedMixin, ModelView):
class BibListesView(FlaskAdminProtectedMixin, RegneAndGroupFormMixin, ModelView):
@property
def can_create(self):
return self._can_action(6)
Expand Down Expand Up @@ -186,21 +187,9 @@ def can_delete(self):
TemplateLinkRowAction("custom_row_actions.truncate_bib_liste", "Effacer cd_nom liste"),
]

form_args = {
"regne": {
"query_factory": lambda: db.session.scalars(
select(VMRegne).where(VMRegne.regne.isnot(None))
)
}
}
create_template = "admin/edit_bib_list.html"
form_columns = ["code_liste", "nom_liste", "desc_liste", "regne", "group2_inpn"]

def on_model_change(self, form, model, is_created):
"""
Force None on empty string regne
"""
if model.regne and not model.regne.regne:
model.regne = None
create_template = "admin/edit_bib_list.html"

def render(self, template, **kwargs):
self.extra_js = [
Expand Down Expand Up @@ -262,7 +251,9 @@ def import_cd_nom_view(self, *args, **kwargs):

return redirect(self.get_url(".index_view"))

return self.render("admin/populate_biblist.html", form=form)
return self.render(
"admin/populate_biblist.html", form=form, return_url=self.get_url(".index_view")
)


class InlineMediaForm(InlineFormAdmin):
Expand Down Expand Up @@ -331,6 +322,9 @@ def _apply_search(self, query, count_query, joins, count_joins, search):

column_searchable_list = ["nom_complet", "cd_nom"]

# ATTENTION : les tests se basent sur les indices
# de ce tableau. Rajouter des filtres à la fin, ou changer les
# indice des filtres dans les tests (fonction `get_list`)
column_filters = [
FilterEqual(Taxref.cd_nom, name="cd_nom"),
FilterEqual(Taxref.cd_ref, name="cd_ref"),
Expand Down Expand Up @@ -368,11 +362,11 @@ def _apply_search(self, query, count_query, joins, count_joins, search):
def _get_theme_attributes(self, taxon):
return (
db.session.query(BibThemes)
.filter(or_(BibAttributs.v_regne == taxon.regne, BibAttributs.v_regne == None))
.filter(or_(BibAttributs.regne == taxon.regne, BibAttributs.regne == None))
.filter(
or_(
BibAttributs.v_group2_inpn == taxon.group2_inpn,
BibAttributs.v_group2_inpn == None,
BibAttributs.group2_inpn == taxon.group2_inpn,
BibAttributs.group2_inpn == None,
)
)
.order_by(BibAttributs.ordre)
Expand Down Expand Up @@ -558,7 +552,7 @@ def get_list(self, query, offset=0, limit=DEFAULT_PAGE_SIZE):
return Taxref.query.with_entities(Taxref.regne).distinct().all()


class BibAttributsView(FlaskAdminProtectedMixin, ModelView):
class BibAttributsView(FlaskAdminProtectedMixin, RegneAndGroupFormMixin, ModelView):

form_base_class = TAdditionalAttributForm

Expand Down Expand Up @@ -590,8 +584,6 @@ def can_delete(self):
"group2_inpn",
)

create_template = "admin/edit_attr.html"

column_labels = {
"desc_attribut": "Description",
"regne": "Règne",
Expand All @@ -604,11 +596,17 @@ def can_delete(self):
"liste_valeur_attribut": """Doit suivre le format suivant: {"values":[valeur1, valeur2, valeur3]}"""
}

def liste_valeur_attribut_formater(v, c, m, p):
if m.liste_valeur_attribut:
data = json.loads(m.liste_valeur_attribut)
if "values" in data:
return ", ".join(data["values"])
return ""

column_formatters = {
"liste_valeur_attribut": lambda v, c, m, p: ", ".join(
json.loads(m.liste_valeur_attribut)["values"]
),
"liste_valeur_attribut": liste_valeur_attribut_formater,
}
create_template = "admin/edit_attr.html"

def render(self, template, **kwargs):
self.extra_js = [
Expand All @@ -617,13 +615,6 @@ def render(self, template, **kwargs):

return super(BibAttributsView, self).render(template, **kwargs)

def on_model_change(self, form, model, is_created):
"""
Force None on empty string regne
"""
if model.regne and not model.regne.regne:
model.regne = None

form_choices = {
"type_attribut": [
("int", "int"),
Expand All @@ -639,11 +630,3 @@ def on_model_change(self, form, model, is_created):
("text", "text"),
],
}

form_args = {
"regne": {
"query_factory": lambda: db.session.scalars(
select(VMRegne).where(VMRegne.regne.isnot(None))
)
}
}
50 changes: 50 additions & 0 deletions apptax/admin/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from flask_admin.contrib.sqla.fields import QuerySelectField
from flask_admin.form.fields import Select2Field
from sqlalchemy import select

from apptax.database import db
from apptax.taxonomie.models import VMRegne, VMGroup2Inpn

from flask_admin.contrib.sqla.fields import QuerySelectField
from flask_admin.form.fields import Select2Field
from sqlalchemy import select

from apptax.database import db
from apptax.taxonomie.models import VMRegne, VMGroup2Inpn


class RegneAndGroupFormMixin:
form_overrides = {"regne": QuerySelectField, "group2_inpn": QuerySelectField}

form_args = {
"regne": {
"query_factory": lambda: db.session.scalars(
select(VMRegne).where(VMRegne.regne.isnot(None))
).all(),
"allow_blank": True,
},
"group2_inpn": {
"query_factory": lambda: db.session.scalars(
select(VMGroup2Inpn).where(VMGroup2Inpn.group2_inpn.isnot(None))
),
"allow_blank": True,
},
}

def on_model_change(self, form, model, is_created):
"""
Force None on empty string regne
and put transform orm object in str
"""
# HACK otherwise QuerySelectField insert the VRegne object ..
# Select2Fields with choices does not work because choices list
# is load when app is loaded (its a probleme for migrations)
if model.regne:
model.regne = model.regne.regne
if model.regne == "":
model.regne = None

if model.group2_inpn:
model.group2_inpn = model.group2_inpn.group2_inpn
if model.group2_inpn == "":
model.group2_inpn = None
3 changes: 2 additions & 1 deletion apptax/admin/templates/admin/details_taxref.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ <h5 class="card-title col-1">

<div class="tab-pane fade" id="nav-lists" role="tabpanel" aria-labelledby="nav-lists-tab">
<table class="table table-striped mt-3">
{% for liste in model.liste %}
{{model.liste}}
{% for liste in model.listes %}
<tr>
<td>
{{ liste }}
Expand Down
2 changes: 1 addition & 1 deletion apptax/admin/templates/admin/populate_biblist.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ <h1>Peupler la liste</h1>
{% block edit_form %}
{% call lib.form_tag(action=action) %}
{{ lib.render_form_fields(form, form_opts=form_opts) }}
{{ lib.render_form_buttons(cancel_url, extra, is_modal) }}
{{ lib.render_form_buttons(return_url) }}
{% endcall %}
{% endblock %}
</div>
Expand Down
13 changes: 12 additions & 1 deletion apptax/admin/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,15 @@ def populate_bib_liste(id_list, delimiter, with_header, file):
if with_header:
next(inputcsv, None)

taxa_set = set()
for row in inputcsv:
# Si la ligne est vide
if not row:
break
# Si la valeur du cd_nom est vide
if not row[0]:
break

try:
cd_nom = int(row[0])
except (TypeError, ValueError):
Expand All @@ -68,6 +76,9 @@ def populate_bib_liste(id_list, delimiter, with_header, file):

tax = Taxref.query.get(cd_nom)
if tax:
tax.listes.append(bibliste)
# add in a set to avoid doublon -> integrity error
taxa_set.add(tax)
for new_name in taxa_set:
bibliste.noms.append(new_name)

db.session.commit()
18 changes: 10 additions & 8 deletions apptax/taxonomie/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class VMRegne(db.Model):
def __repr__(self):
return self.regne

def __str__(self):
return self.regne


@serializable
class VMGroup2Inpn(db.Model):
Expand All @@ -31,6 +34,9 @@ class VMGroup2Inpn(db.Model):
def __repr__(self):
return self.group2_inpn

def __str__(self):
return self.group2_inpn


@serializable
class CorTaxonAttribut(db.Model):
Expand Down Expand Up @@ -84,14 +90,14 @@ class BibAttributs(db.Model):
desc_attribut = db.Column(db.Text)
type_attribut = db.Column(db.Unicode)
type_widget = db.Column(db.Unicode, nullable=False)
v_regne = db.Column(
regne = db.Column(
db.Unicode,
ForeignKey(VMRegne.regne),
name="regne",
nullable=True,
primary_key=False,
)
v_group2_inpn = db.Column(
group2_inpn = db.Column(
db.Unicode,
ForeignKey(VMGroup2Inpn.group2_inpn),
name="group2_inpn",
Expand All @@ -106,8 +112,6 @@ class BibAttributs(db.Model):
)
ordre = db.Column(db.Integer)
theme = db.relationship(BibThemes)
regne = db.relationship(VMRegne)
group2_inpn = db.relationship(VMGroup2Inpn)

def __repr__(self):
return self.nom_attribut
Expand Down Expand Up @@ -228,14 +232,14 @@ class BibListes(db.Model):
code_liste = db.Column(db.Unicode)
nom_liste = db.Column(db.Unicode)
desc_liste = db.Column(db.Text)
v_regne = db.Column(
regne = db.Column(
db.Unicode,
ForeignKey(VMRegne.regne),
name="regne",
nullable=True,
primary_key=False,
)
v_group2_inpn = db.Column(
group2_inpn = db.Column(
db.Unicode,
ForeignKey(VMGroup2Inpn.group2_inpn),
name="group2_inpn",
Expand All @@ -244,8 +248,6 @@ class BibListes(db.Model):
)

noms = db.relationship("Taxref", secondary=cor_nom_liste, back_populates="listes")
regne = db.relationship("VMRegne")
group2_inpn = db.relationship("VMGroup2Inpn")

@hybrid_property
def nb_taxons(self):
Expand Down
12 changes: 4 additions & 8 deletions apptax/taxonomie/routesbiblistes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ def get_biblistes(id=None):
et le nombre d'enregistrements dans "count"
"""
data = db.session.query(BibListes).all()
biblistes_schema = BibListesSchema(
exclude=("v_regne", "v_group2_inpn"), only=("+regne", "+group2_inpn")
)
biblistes_schema = BibListesSchema()
maliste = {"data": [], "count": 0}
maliste["count"] = len(data)
maliste["data"] = biblistes_schema.dump(data, many=True)
Expand All @@ -44,13 +42,11 @@ def get_biblistes(id=None):
def get_biblistesbyTaxref(regne, group2_inpn):
q = db.session.query(BibListes)
if regne:
q = q.where(BibListes.v_regne == regne)
q = q.where(BibListes.regne == regne)
if group2_inpn:
q = q.where(BibListes.v_group2_inpn == group2_inpn)
q = q.where(BibListes.group2_inpn == group2_inpn)
results = q.all()
return BibListesSchema(
exclude=("v_regne", "v_group2_inpn"), only=("+regne", "+group2_inpn")
).dump(results, many=True)
return BibListesSchema().dump(results, many=True)


@adresses.route("/cor_nom_liste", methods=["GET"])
Expand Down
Loading

0 comments on commit 355aa68

Please sign in to comment.