Django FilterSet для полей JSON
Например, У меня есть простая django-модель:
class SimpleModel(models.Model):
some_attr = models.JSONField() #there is [attr1, attr2, ...] in JSON
Простой вид:
class SimpleView(ListCreateApivView):
filter_backends = [DjangoFilterBackend, ]
filterset_class = SimpleFilter
И простой фильтр:
class SimpleFilter(django_filters.FilterSet):
class Meta:
model = SimpleModel
fields = {'some_attr': ['icontains', ]}
Я хочу проверить, является ли http://127.0.0.1/simple?some_attr__icontains=['Something, что у меня есть в db']. В моей базе данных есть JSONField, который содержит [a1, a2, a3 ...], поэтому, как я могу проверить, находится ли значение из url в JSONField базы данных?
Я бы переопределил метод get_queryset следующим образом:
views.py
import json
class SimpleView(...):
...
def get_queryset(self):
# unpack the filter:
filter_string = self.request.GET.get('filter', {})
filter_dictionary = json.loads(filter_string)
# filter queryset:
queryset = self.queryset.filter(**filter_dictionary)
return queryset
Тогда вы можете сделать что-то вроде этого с фронтенда:
scripts.js
// create a django like filter:
var filter = JSON.stringify({
some_attr__some_key__icontains : 'some_value'
});
// add the filter as a parameter to the url:
var url = 'api/simple_model/?filter=' + filter;
// send the request:
$.ajax({
url : url,
...
});
Спасибо за ответ, Я решил проблему созданием пользовательского фильтра для моего JSON-поля, примерно так:
class CharInFilter(filters.BaseInFilter, filters.CharFilter):
pass
class MainInfoFilter(filters.FilterSet):
some_attr = CharInFilter(method='some_attr_filter')
def some_attr_filter(self, queryset, name, value):
query = Q()
for type in value:
query |= Q(license_types__icontains=type)
if query:
queryset = queryset.filter(query)
return queryset
Попробуйте, это вам поможет. В моем случае я использовал JSON-поле для столбца job_location в файле Django model.py. Когда я пытаюсь применить django_filter, то сталкиваюсь с этой ошибкой, которую решаю следующим образом.
этот код вводится в файл представления.
from django_filters import rest_framework as filters
class ProductFilter(filters.FilterSet):
job_location = filters.CharFilter(field_name="job_location", lookup_expr='icontains')
class Meta:
model = JobPostModel
fields = {
'job_location': ['exact',],
}
django_filter, используемый в этом классе
from django_filters.rest_framework import DjangoFilterBackend
class JobsView(generics.ListAPIView):
queryset = JobPostModel.objects.all()
serializer_class = JobPostSerializer
filter_backends = (DjangoFilterBackend)
filterset_class = ProductFilter
и ищите в браузере по URL
http://127.0.0.1:8000/jobs/?job_location=mumbai