Фильтр Django Rest Framework на основе вложенных объектов JSONField
Я работаю над проектом с использованием Python(3), Django(1.11) и DRF, в котором я должен фильтровать данные на основе json
поле объекта, которое сохраняется как JSONFIELD
в модели дб.
Вот что я попробовал:
model.py:
from django.db import models
import jsonfield
class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=255)
type = models.CharField(max_length=255)
props = jsonfield.JSONField()
repo = jsonfield.JSONField()
created_at = models.DateTimeField()
serializers.py
:
class MyModelSerializer(serializers.ModelSerializer):
props = serializers.JSONField()
repo = serializers.JSONField()
class Meta:
model = EventModel
fields = "__all__"
Json object
:
{
"id":4633249595,
"type":"PushEvent",
"props":{
"id":4276597,
"login":"iholloway",
"avatar_url":"https://avatars.com/4276597"
},
"repo":{
"id":269910,
"name":"iholloway/aperiam-consectetur",
"url":"https://github.com/iholloway/aperiam-consectetur"
},
"created_at":"2016-04-18 00:13:31"
}
views.py:
class PropsEvents(generics.RetrieveAPIView):
serializer_class = MyModelSerializer
def get_object(self):
print(self.request.parser_context['kwargs']['id'])
queryset = MyModel.objects.filter(data__props__id=self.request.parser_context['kwargs']['id'])
obj = get_object_or_404(queryset)
return obj
Он должен вернуть записи MyModel по
props ID
и должен быть в состоянии вернуть массив JSON всехMyModel objects
гдеprops ID
по запросу GET на/mymodel/props/<ID>
, Если запрошенныйprops
не существует, тогда код ответа HTTP должен быть 404, в противном случае код ответа должен быть 200. Массив JSON должен быть отсортирован в порядке возрастания по идентификатору MyModel.
Когда я отправил запрос в это представление, он возвращает ошибку:
django.core.exceptions.FieldError: Unsupported lookup 'id' for JSONField or join on the field not permitted. [18/Feb/2019 10:37:39] "GET /events/actors/2790311/ HTTP/1.1" 500 16210
Итак, как я могу отфильтровать объекты на основе id of props
?
Помоги мне, пожалуйста! Заранее спасибо!
2 ответа
Функция, которую вы ищете, возможна, к сожалению, это не так просто. Насколько я знаю, это не поддерживается jsonfield
пакет, но вместо этого вам придется использовать Postgres в качестве базы данных и использовать его внутренний JSONField. Я думаю, что вы можете выбрать один из следующих:
- переключиться на
django.contrib.postgres.fields.JSONField
и использовать Postgres в качестве базы данных вашей базы данных во всех средах (а затем поддерживать такие поиски) - заставить данные следовать определенной схеме и изменить JSONField на отдельную модель и таблицу
- использовать гибридное решение для хранения с выделенным решением для документов JSON
- Извлеките поля, к которым необходимо выполнить запрос, в вашу модель - включив запрос, но сохранив неструктурированные данные в JSONField.
class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=255)
type = models.CharField(max_length=255)
props = jsonfield.JSONField()
props_id = models.IntegerField(null=True)
repo = jsonfield.JSONField()
repo_id = models.IntegerField(null=True)
created_at = models.DateTimeField()
А затем установите значения идентификатора вручную или в save()
модели:
def save(self, *args, **kwargs):
self.repo_id = self.repo.get("id")
self.props_id = self.props.get("id")
return super().save(*args, **kwargs)
Вы должны использовать
from django.contrib.postgres.fields import JSONField
Вместо
import jsonfield
И после этого я думаю, что все должно работать правильно