Django-filter: Pemfilteran berdasarkan Atribut Model Kunci Asing

Dibuat pada 9 Jan 2019  ·  4Komentar  ·  Sumber: carltongibson/django-filter

Hai, yang di sana!

Saya sedang mengerjakan sebuah masalah di tempat kerja dan bertanya-tanya apa cara paling idiomatis untuk mengatasinya. Kami memiliki beberapa bidang filter ModelMultipleChoiceFilter untuk kunci asing suatu model. Saya mencoba mencari cara memfilter berdasarkan atribut unik pada kunci asing saat menggunakan widget CheckboxSelectMultiple , tanpa memperlihatkan kunci utama di URL.

Berikut adalah contoh yang (kurang lebih) menunjukkan bagaimana saya mengaturnya sekarang.

# 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']

Ini bekerja sangat baik dalam tampilan. Filter berfungsi dan memfilter dengan benar dengan widget yang tepat. Namun, url memiliki kunci utama di dalamnya, jadi dalam contoh ini /?foo=1 , sedangkan saya ingin itu membaca /?foo=<prop value> , untuk mencegah mengekspos pk saya serta membuat url lebih mudah dibaca.

Saya mencoba memodifikasi bidang seperti ini, karena di tempat lain di Django cenderung berfungsi:

# app/filters.py
...snip...
    class Meta:
        model = bar
        fields = ['foo__prop']

Ini membuat url merespons /?foo=<prop value> seperti yang diinginkan, tetapi sekarang tidak menggunakan CheckboxSelectMultiple untuk formulir. Saya mencoba membuat atribut menjadi foo__prop juga, tetapi rendering formulir masih salah.

Saya merasa apa yang saya coba lakukan didukung mengingat ini hampir berhasil, tetapi sepertinya saya tidak tahu bagaimana cara mendapatkannya. Jika ini di luar cakupan yang didukung saat ini, saya dapat menulis formulir saya sendiri untuk menangani ini. Terima kasih banyak atas bantuan apa pun dan untuk proyek yang luar biasa!

Komentar yang paling membantu

Hai, terima kasih telah meluangkan waktu untuk membalas!

Anda telah mengatur saya di jalur yang benar! Saya mendapat kesempatan untuk mengimplementasikan ini kemarin, dan menggunakan argumen field_name berhasil!

Bagi siapa pun di masa mendatang yang mungkin membaca masalah ini, berikut kira-kira bagaimana kode tersebut keluar:

# 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']

Anda dapat menemukan referensi untuk ini di dokumentasi @carltongibson yang disebutkan di atas utas. Secara khusus, lihat bagian filter ModelMultipleChoice.

Bagaimanapun, terima kasih banyak telah meluangkan waktu untuk membantu saya!

Semua 4 komentar

Hai. Masalah yang bagus. Benar-benar pertanyaan penggunaan, tetapi sangat menyenangkan untuk dibaca.

Apakah Anda melihat argumen field_name ke filter?
https://django-filter.readthedocs.io/en/master/ref/filters.html

Ini akan memungkinkan Anda untuk menggunakan foo_prop sebagai target untuk filter foo Anda.

Saya membayangkan itu akan berhasil ... mungkin Anda perlu mengatur pilihan pada widget atau semacamnya (tapi itu harus ditangani ...)

Hai, terima kasih telah meluangkan waktu untuk membalas!

Anda telah mengatur saya di jalur yang benar! Saya mendapat kesempatan untuk mengimplementasikan ini kemarin, dan menggunakan argumen field_name berhasil!

Bagi siapa pun di masa mendatang yang mungkin membaca masalah ini, berikut kira-kira bagaimana kode tersebut keluar:

# 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']

Anda dapat menemukan referensi untuk ini di dokumentasi @carltongibson yang disebutkan di atas utas. Secara khusus, lihat bagian filter ModelMultipleChoice.

Bagaimanapun, terima kasih banyak telah meluangkan waktu untuk membantu saya!

Super. Senang Anda memecahkannya. Sudah selesai dilakukan dengan baik!

Kerja bagus ! Terima kasih !

Apakah halaman ini membantu?
0 / 5 - 0 peringkat