Salut!
Je travaillais sur un problème au travail et je me demandais quelle était la manière la plus idiomatique de l'aborder. Nous avons plusieurs champs de filtre ModelMultipleChoiceFilter
pour les clés étrangères d'un modèle. J'essaie de comprendre comment filtrer par un attribut unique sur les clés étrangères tout en utilisant un widget CheckboxSelectMultiple
, sans exposer les clés primaires dans les URL.
Voici un exemple qui montre (plus ou moins) comment je l'ai configuré en ce moment.
# app/models.py
from django.db import models
class Foo(models.Model):
prop = models.CharField(max_length=55, unique=True)
def __str__(self):
return self.name
class Bar(models.Model):
foo = models.ForeignKey(Foo, related_name="bars")
# app/filters.py
import django_filters
from app.models import Bar, Foo
class BarFilter(django_filters.FilterSet):
foo = django_filters.ModelMultipleChoiceFilter(
queryset=Foo.objects.all(),
widget=CheckboxSelectMultiple(),
label="Foo",
label_suffix="",
)
class Meta:
model = bar
fields = ['foo']
Cela fonctionne très bien dans la vue. Les filtres fonctionnent et filtrent correctement avec les bons widgets. Cependant, l'url contient la clé primaire, donc dans cet exemple /?foo=1
, alors que je veux qu'elle lise /?foo=<prop value>
, pour éviter d'exposer mon pk et rendre les URL plus lisibles.
J'ai essayé de modifier des champs comme celui-ci, car ailleurs dans Django, cela a tendance à fonctionner :
# app/filters.py
...snip...
class Meta:
model = bar
fields = ['foo__prop']
Cela fait que l'url répond à /?foo=<prop value>
comme vous le souhaitez, mais maintenant elle n'utilise pas CheckboxSelectMultiple
pour le formulaire. J'ai également essayé de transformer l'attribut en foo__prop
, mais le rendu du formulaire était toujours incorrect.
J'ai le sentiment que ce que j'essaie de faire est pris en charge étant donné que cela fonctionne presque, mais je n'arrive pas à comprendre comment l'obtenir. Si cela est en dehors de la portée actuellement prise en charge, je peux écrire mon propre formulaire pour gérer cela. Merci beaucoup pour toute aide et pour le projet génial!
Salut. Belle question. Strictement une question d'utilisation, mais si bien posée, c'est un plaisir à lire.
Avez-vous regardé l'argument field_name pour les filtres ?
https://django-filter.readthedocs.io/en/master/ref/filters.html
Cela vous permettrait d'utiliser foo_prop comme cible pour votre filtre foo.
J'imagine que cela fonctionnerait... peut-être que vous auriez besoin de définir des choix sur le widget ou autre (mais cela devrait être géré...)
Bonjour, merci d'avoir pris le temps de répondre !
Vous m'avez mis sur la bonne voie ! J'ai eu la chance de l'implémenter hier, et l'utilisation de l'argument field_name
fonctionné !
Pour toute personne susceptible de lire ce numéro à l'avenir, voici à peu près comment le code est sorti :
# app/filters.py
...snip
class BarFilter(django_filters.FilterSet):
foo = django_filters.ModelMultipleChoiceFilter(
queryset=Foo.objects.all(),
field_name="foo__prop", # This lets us keep the url as "/?foo=<value>
to_field_name="prop",
widget=CheckboxSelectMultiple(),
label="Foo",
label_suffix="",
)
class Meta:
model = bar
fields = ['foo']
Vous pouvez trouver une référence à cela dans la documentation @carltongibson mentionnée en haut du fil. Plus précisément, consultez la section sur les filtres ModelMultipleChoice.
En tout cas merci beaucoup d'avoir pris le temps de m'aider !
Super. Content que tu l'aies résolu. Bien fait!
Bon travail ! Merci !
Commentaire le plus utile
Bonjour, merci d'avoir pris le temps de répondre !
Vous m'avez mis sur la bonne voie ! J'ai eu la chance de l'implémenter hier, et l'utilisation de l'argument
field_name
fonctionné !Pour toute personne susceptible de lire ce numéro à l'avenir, voici à peu près comment le code est sorti :
Vous pouvez trouver une référence à cela dans la documentation @carltongibson mentionnée en haut du fil. Plus précisément, consultez la section sur les filtres ModelMultipleChoice.
En tout cas merci beaucoup d'avoir pris le temps de m'aider !