[PYTHON] Verstehen Sie, wie man Django-Filter verwendet

Was ist ein Django-Filter?

Sie können Ihre Suchkriterien in Funktionscode schreiben !!! Als ich das lernte, dachte ich, es sei revolutionär.

offizielles Django-Filter-Dokument

Modell und Seiralizer definieren

Definieren wir als Beispiel ein solches Modell und einen solchen Serializer.

models.py


class Book(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    is_deleted = models.CharField(max_length=1, default='0')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    title = models.CharField(max_length=128)
    sub_title = models.CharField(max_length=128)
    price = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
    author = models.ForeignKey(Author, on_delete=models.PROTECT, blank=True, null=True)
    publisher = models.ForeignKey(Publisher, on_delete=models.PROTECT)

serializer.py


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

Grundlegendes Schreiben

Zunächst mit Django-Filter Versuchen Sie, die Liste abzurufen, ohne sie durch die Suchbedingungen einzugrenzen.

view.py


from django_filters import rest_framework as filters

class FilterBook(filters.FilterSet):
    class Meta:
        model = Book
        fields = '__all__'

class ListBook(APIView):

    def get(self, request):
        filterset = FilterBook(request.query_params, queryset=Book.objects.all())
        serializer = BookSerializer(instance=filterset.qs, many=True)
        return Response(serializer.data)

Erstellen Sie eine Klasse, die von FilterSet erbt, und geben Sie dort das Modell an. Es ähnelt Djangos Form und Serializer.

Und die URL dieser erstellten ListBook-API / api / v1 / book / list / (weggelassen) Wenn Sie eine Anfrage über den Browser stellen, werden diese Daten zurückgegeben. Natürlich sind die Daten ein Beispiel lol

スクリーンショット 2020-10-21 19.38.42.png

Geben Sie die Suchbedingungen an

Geben Sie dann die Suchbedingungen an und stellen Sie eine Anfrage. Die zuvor angeforderte URL war "/ api / v1 / book / list /", aber geben Sie dort die Abfrageparameter an. Wenn Sie zu / api / v1 / book / list /? Title = test wechseln und anfordern, ändert sich die Antwort.

スクリーンショット 2020-10-21 19.48.30.png

Diesmal wurde keine Antwort zurückgegeben. Dieser title = test gibt ein Objekt zurück, dessen Titel des Buchmodells mit test übereinstimmt. Ändern Sie außerdem "title" in "sub_title" in "/ api / v1 / book / list /? Sub_title = test" Wenn ich eine Anfrage stelle, wird keine Antwort zurückgegeben.

Wenn Sie jedoch einen Abfrageparameter angeben, der im Buchmodell nicht vorhanden ist Daten können nicht eingegrenzt werden und Daten werden in der Antwort zurückgegeben.

Suchbedingungen ändern

Früher eingrenzen durch "title" und "sub_title" Die Daten wurden extrahiert.

Diesmal kann "title" jedoch eine Suchbedingung sein, "sub_title" ist jedoch nicht als Suchbedingung erforderlich! Ich frage mich, was passiert ist. In einem solchen Fall können Sie nur das entsprechende mit "Feldern" der Filterklasse angeben.

views.py


class FilterBook(filters.FilterSet):
    class Meta:
        model = Book
        fields = ['title']

Auf diese Weise konnte ich früher um "sub_title" eingrenzen, aber jetzt kann ich nur noch um "title" eingrenzen.

Passen Sie die Suchmethode an

Wenn Sie zuvor Felder mit "all" angegeben haben, ist dies die Standardsuchmethode. Ich konnte die Suchmethode wie numerische Suche oder teilweise Übereinstimmung nicht verwenden. (Selbst wenn Sie beispielsweise "/ api / v1 / book / list /? Price = test" anfordern, wird dies nicht eingegrenzt.)

Daher werden wir die Suchmethode anpassen.

views.py


class FilterBook(filters.FilterSet):
    # UUID
    id = filters.UUIDFilter()

    #Teilweise Übereinstimmung
    title = filters.CharFilter(lookup_expr='icontains')

    #Finden Sie den Betrag heraus
    price = filters.NumberFilter()
    price__gt = filters.NumberFilter(field_name='price', lookup_expr='gt')
    price__lt = filters.NumberFilter(field_name='price', lookup_expr='lt')

    class Meta:
        model = Book
        fields = []

Der Inhalt der Anpassung. filter.UUIDFilter () entspricht UUID. Selbst wenn Sie nach ID suchen, wird es abgefangen. Mit filter.CharFilter (lookup_expr = 'icontains') Ich habe ein Teilmatch gemacht. Das Argument für diesen lookup_expr ist Djangos Feldsuche Sie können dasselbe angeben wie. filters.NumberFilter(field_name='price', lookup_expr='gt') Gibt die Entsprechung und den Nummernbereich an. Feldname gibt das Zielfeld des Modells an. Wenn der Name des Filterfelds und der Name des Modellfelds übereinstimmen, müssen Sie ihn normalerweise nicht angeben.


Lassen Sie uns nach der Anpassung eine Anfrage stellen. api / v1 / book / list /? title = sql und api/v1/book/list/?price_gt=3200&price_lt=4000 Daten werden jetzt auf Anfrage beantwortet.

スクリーンショット 2020-10-21 20.39.53.png

Unterstützt auch Beziehungen

Wenn Sie das von ForeignKey verknüpfte Modell als Suchbedingung verwenden möchten, Geben Sie in Feldname an. Die Spezifikationsmethode kann von djangos Suchausdruck verwaltet werden.

views.py


class FilterBook(filters.FilterSet):
    author_last_name = filters.CharFilter(field_name='author__last_name',lookup_expr='icontains')

Passen Sie den Standardfilter an

Mit dem Standardfilter musste CharFilter für jedes Feld angepasst werden, z. B. für eine genaue Übereinstimmung. Anstatt Feld für Feld anzupassen, versuchen wir, die CharFilter-Standardeinstellungen anzupassen.

views.py


class FilterBook(filters.FilterSet):

    class Meta:
        model = Book
        fields = ['title']
        filter_overrides = {
            models.CharField: {
                'filter_class': filters.CharFilter,
                'extra': lambda f: {
                    'lookup_expr': 'icontains',
                },
            },
        }

Beschreiben Sie in class Meta: filter_overrrides und den Inhalt, den Sie als Standard festlegen möchten. Jetzt sind alle Felder, die "CharFiled" im Modell verwenden, standardmäßig teilweise abgeglichen.

Nehmen Sie Ihre eigenen Anpassungen vor

Sie können Ihre eigene Suche durchführen, wenn Sie eingrenzen. Ich habe ein Beispiel für das Entfernen von Bindestrichen und das Erstellen einer Teilübereinstimmung erstellt.

views.py


class FilterBook(filters.FilterSet):
    title = filters.CharFilter(method='title_custom_filter')

    class Meta:
        model = Book
        fields = []

    @staticmethod
    def title_custom_filter(queryset, name, value):
        #Name ist der Feldname
        #value ist der Abfrageparameter
        # name__icontains
        lookup = '__'.join([name, 'icontains'])
        #Bindestriche löschen
        replaced_value = value.replace('-', '')
        return queryset.filter(**{
            lookup: replaced_value,
        })

Wenn Sie den Namen der Methode als Zeichenfolge im Argument "CharFilter" übergeben, wird die Methode zum Zeitpunkt der Suche ausgeführt. Der Feldname und die Suchparameter "Wert" werden an "Name" übergeben. Wenn Sie dies ändern, können Sie frei Suchbedingungen erstellen.

Diesmal zum Beispiel Gleich wie / api / v1 / book / list /? Title = g /api/v1/book/list/?title=g--- Sie können jetzt eine Antwort erhalten, auch wenn Sie eine Anfrage an senden.

スクリーンショット 2020-10-22 1.38.34.png


Weitere Informationen finden Sie unter Auf jeden Fall offizielles Dokument Ich hoffe du kannst es überprüfen !!!!!!!!!!!!!!!!!

Recommended Posts

Verstehen Sie, wie man Django-Filter verwendet
Verwendung von xml.etree.ElementTree
Wie benutzt man Python-Shell
Hinweise zur Verwendung von tf.data
Verwendung von virtualenv
Wie benutzt man Seaboan?
Verwendung von Image-Match
Wie man Shogun benutzt
Verwendung von Pandas 2
Verwendung von Virtualenv
Verwendung von numpy.vectorize
Verwendung von pytest_report_header
Wie man teilweise verwendet
Wie man Bio.Phylo benutzt
Verwendung von SymPy
Wie man x-means benutzt
Verwendung von WikiExtractor.py
Verwendung von IPython
Verwendung von virtualenv
Wie benutzt man Matplotlib?
Verwendung von iptables
Wie benutzt man numpy?
Verwendung von TokyoTechFes2015
Wie benutzt man venv
Verwendung des Wörterbuchs {}
Wie benutzt man Pyenv?
Verwendung der Liste []
Wie man Python-Kabusapi benutzt
[Python] Verstehen, wie rekursive Funktionen verwendet werden
Verwendung von OptParse
Verwendung von return
Wie man Imutils benutzt
Verwendung von Qt Designer
Verwendung der Suche sortiert
[gensim] Verwendung von Doc2Vec
python3: Verwendung der Flasche (2)
Verwendung des Generators
[Python] Verwendung von Liste 1
Verwendung von FastAPI ③ OpenAPI
Wie benutzt man Python Argparse?
Verwendung von IPython Notebook
Wie man Pandas Rolling benutzt
[Hinweis] Verwendung von virtualenv
Verwendung von Redispy-Wörterbüchern
Python: Wie man pydub benutzt
[Python] Verwendung von checkio
[Go] Verwendung von "... (3 Perioden)"
So bedienen Sie GeoIp2 von Django
[Python] Verwendung von input ()
Wie benutzt man den Dekorateur?
[Einführung] Verwendung von open3d
Wie benutzt man Python Lambda?
So verwenden Sie Jupyter Notebook
[Python] Verwendung von virtualenv
python3: Verwendung der Flasche (3)
python3: Wie man eine Flasche benutzt
So verwenden Sie Google Colaboratory