Sie können Ihre Suchkriterien in Funktionscode schreiben !!! Als ich das lernte, dachte ich, es sei revolutionär.
offizielles Django-Filter-Dokument
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__'
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
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.
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.
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.
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.
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')
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.
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.
Weitere Informationen finden Sie unter Auf jeden Fall offizielles Dokument Ich hoffe du kannst es überprüfen !!!!!!!!!!!!!!!!!
Recommended Posts