Hi!
Ich habe bei der Arbeit an einem Problem gearbeitet und mich gefragt, wie man es am idiomatischsten angeht. Wir haben mehrere ModelMultipleChoiceFilter
Filterfelder für Fremdschlüssel eines Modells. Ich versuche herauszufinden, wie man bei Verwendung eines CheckboxSelectMultiple
Widgets nach einem eindeutigen Attribut für die Fremdschlüssel filtert, ohne Primärschlüssel in den URLs offenzulegen.
Hier ist ein Beispiel, das (mehr oder weniger) zeigt, wie ich es gerade eingerichtet habe.
# 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']
Das funktioniert in der Ansicht ganz gut. Die Filter funktionieren und filtern korrekt mit den richtigen Widgets. Die URL enthält jedoch den Primärschlüssel, also in diesem Beispiel /?foo=1
, während ich möchte, dass sie /?foo=<prop value>
lautet, um zu verhindern, dass mein pk preisgegeben wird und URLs lesbarer werden.
Ich habe versucht, Felder wie folgt zu ändern, weil es anderswo in Django dazu neigt, zu funktionieren:
# app/filters.py
...snip...
class Meta:
model = bar
fields = ['foo__prop']
Dadurch reagiert die URL wie gewünscht auf /?foo=<prop value>
, verwendet aber jetzt nicht mehr CheckboxSelectMultiple
für das Formular. Ich habe auch versucht, das Attribut zu foo__prop
zu machen, aber das Rendern des Formulars war immer noch falsch.
Ich habe das Gefühl, dass das, was ich versuche, unterstützt wird, wenn man bedenkt, dass es fast funktioniert, aber ich kann nicht ganz herausfinden, wie ich es hinbekomme. Wenn dies außerhalb des derzeit unterstützten Bereichs liegt, kann ich mein eigenes Formular schreiben, um dies zu handhaben. Vielen Dank für jede Hilfe und für das tolle Projekt!
Hallo. Schöne Angelegenheit. Streng genommen eine Verwendungsfrage, aber so gut formuliert, dass es ein Vergnügen ist, es zu lesen.
Haben Sie sich das Argument field_name für Filter angesehen?
https://django-filter.readthedocs.io/en/master/ref/filters.html
Auf diese Weise können Sie foo_prop als Ziel für Ihren foo-Filter verwenden.
Ich könnte mir vorstellen, dass das einfach funktioniert ... vielleicht müssen Sie Optionen für das Widget oder so einstellen (aber das sollte behandelt werden ...)
Hallo, vielen Dank, dass Sie sich die Zeit genommen haben zu antworten!
Sie haben mich auf den richtigen Weg gebracht! Ich hatte gestern die Gelegenheit, dies zu implementieren, und die Verwendung des Arguments field_name
funktioniert!
Für alle, die dieses Problem in Zukunft lesen könnten, hier ungefähr, wie der Code herausgekommen ist:
# 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']
Einen Hinweis darauf finden Sie in der Dokumentation @carltongibson, die oben erwähnt wurde. Siehe insbesondere den Abschnitt zu ModelMultipleChoice-Filtern.
Trotzdem vielen Dank, dass Sie sich die Zeit genommen haben, mir zu helfen!
Super. Schön, dass du es gelöst hast. Gut erledigt!
Gut gemacht ! Dankeschön !
Hilfreichster Kommentar
Hallo, vielen Dank, dass Sie sich die Zeit genommen haben zu antworten!
Sie haben mich auf den richtigen Weg gebracht! Ich hatte gestern die Gelegenheit, dies zu implementieren, und die Verwendung des Arguments
field_name
funktioniert!Für alle, die dieses Problem in Zukunft lesen könnten, hier ungefähr, wie der Code herausgekommen ist:
Einen Hinweis darauf finden Sie in der Dokumentation @carltongibson, die oben erwähnt wurde. Siehe insbesondere den Abschnitt zu ModelMultipleChoice-Filtern.
Trotzdem vielen Dank, dass Sie sich die Zeit genommen haben, mir zu helfen!