django-elasticsearch-dsl type' attrlist的对象'不是JSON可序列化
我有一个Django应用程序,需要在此应用程序中实现搜索系统,对于此应用程序,Elasticsearch似乎是最合适的,但是我遇到了一个无法解决的问题。
我在Postgres中有一列JSONB类似的表格:
[
{
"act": 1900,
"max": 2850,
"min": 2850,
"tgt": 2850,
"desc": "L - Durchsatz (kg/h)",
"name": "L - Durchsatz (kg/h)",
"unit": "kg/h",
"color": "red",
"ordering": 1,
"monitoring": true
},
{
"act": 283,
"max": 425,
"min": 425,
"tgt": 425,
"desc": "L - Siebbandgeschwindigkeit (m/min)",
"name": "L - Siebbandgeschwindigkeit (m/min)",
"unit": "m/min",
"color": "red",
"ordering": 2,
"monitoring": true
},
...
]
Django模型:
class Collect(models.Model):
recipe = models.ForeignKey(RecipeSentHistory, on_delete=models.CASCADE, null=True, default='1')
general_info = models.JSONField(default=dict)
record = models.JSONField(default=dict)
justify = models.CharField(max_length=255, default='*')
automatic = models.BooleanField(default=False)
user = models.CharField(max_length=255, default='*')
user_job_position = models.CharField(max_length=255, default='*')
timestamp = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.recipe.machine.name
我的serializer:
class MyCollectSerializer(serializers.ModelSerializer):
class Meta:
model = Collect
fields = [
'justify',
'record',
'user',
'user_job_position',
'timestamp',
'automatic',
'recipe_id',
'general_info',
]
read_only = True
我的documents.py:
from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
from mpa.models import Collect
@registry.register_document
class CollectDocument(Document):
general_info = fields.ObjectField(
properties={
'batch': fields.TextField(),
'machine': fields.TextField(),
'recipe_cep': fields.TextField(),
'recipe_mpa': fields.TextField(),
'fabrication_order': fields.TextField(),
}
)
record = fields.NestedField()
def prepare_general_info(self, instance):
return instance.general_info
def prepare_record(self, instance):
return instance.record
class Index:
name = 'collect'
class Django:
model = Collect
fields = [
'justify',
'user',
'user_job_position',
'timestamp',
'automatic',
]
我的视图:
from dataclasses import fields
from django.http import HttpResponse
from elasticsearch_dsl import Q
from rest_framework.views import APIView
from rest_framework.pagination import LimitOffsetPagination
from mpa.serializers import MyCollectSerializer
from .documents import CollectDocument
from json import JSONEncoder
from rest_framework.renderers import JSONRenderer
from rest_framework.views import APIView
class JSONSearchEncoder(JSONEncoder):
def default(self, obj):
from elasticsearch_dsl import InnerDoc
if isinstance(obj, InnerDoc):
return obj.to_dict()
return super().default(obj)
class JSONSearchRenderer(JSONRenderer):
encoder_class = JSONSearchEncoder
class GeneralSearchAPIView(APIView):
renderer_classes = (JSONSearchRenderer,)
class SearchCollect(GeneralSearchAPIView, LimitOffsetPagination):
collect_serializer = MyCollectSerializer
search_document = CollectDocument
def get(self, request, query):
try:
q = Q(
'multi_match',
query=query,
fields=[
'user',
]
)
search = self.search_document.search().query(q)
response = search.execute()
results = self.paginate_queryset(
response, request, view=self)
serializer = self.collect_serializer(results, many=True)
return self.get_paginated_response(serializer.data)
except Exception as e:
return HttpResponse(e, status=500)
命令'python manage.py search_index -rebuild-rebuild'正常工作,但是恢复数据时我会收到以下错误:
Environment:
Request Method: GET
Request URL: http://localhost:8000/search/GER02
Django Version: 3.2.12
Python Version: 3.9.12
Installed Applications:
['corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_apscheduler',
'mes.apps.MesConfig',
'collector.apps.CollectorConfig',
'vla.apps.VlaConfig',
'mpa.apps.MpaConfig',
'search.apps.SearchConfig',
'authentication',
'crispy_forms',
'rest_framework',
'simple_history',
'tz_detect',
'django_elasticsearch_dsl']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'simple_history.middleware.HistoryRequestMiddleware',
'tz_detect.middleware.TimezoneMiddleware',
'mpa.middlewares.middleware.userLanguageMiddleware',
'mpa.middlewares.middleware.userTimeZoneMiddleware']
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 204, in _get_response
response = response.render()
File "/usr/local/lib/python3.9/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/usr/local/lib/python3.9/site-packages/rest_framework/response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/usr/local/lib/python3.9/site-packages/rest_framework/renderers.py", line 100, in render
ret = json.dumps(
File "/usr/local/lib/python3.9/site-packages/rest_framework/utils/json.py", line 25, in dumps
return json.dumps(*args, **kwargs)
File "/usr/local/lib/python3.9/json/__init__.py", line 234, in dumps
return cls(
File "/usr/local/lib/python3.9/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/lib/python3.9/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/app/search/views.py", line 18, in default
return super().default(obj)
File "/usr/local/lib/python3.9/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
Exception Type: TypeError at /search/GER02
Exception Value: Object of type AttrList is not JSON serializable
我该怎么办才能将该字段的数据返回包含词典的列表?
感谢任何帮助。
I have a Django application where I need to implement a search system, for this application, elasticsearch seems to be the most suitable, but I came across a problem that I can't solve.
I have in postgres a table with a column of type jsonb similar to this:
[
{
"act": 1900,
"max": 2850,
"min": 2850,
"tgt": 2850,
"desc": "L - Durchsatz (kg/h)",
"name": "L - Durchsatz (kg/h)",
"unit": "kg/h",
"color": "red",
"ordering": 1,
"monitoring": true
},
{
"act": 283,
"max": 425,
"min": 425,
"tgt": 425,
"desc": "L - Siebbandgeschwindigkeit (m/min)",
"name": "L - Siebbandgeschwindigkeit (m/min)",
"unit": "m/min",
"color": "red",
"ordering": 2,
"monitoring": true
},
...
]
Django Model:
class Collect(models.Model):
recipe = models.ForeignKey(RecipeSentHistory, on_delete=models.CASCADE, null=True, default='1')
general_info = models.JSONField(default=dict)
record = models.JSONField(default=dict)
justify = models.CharField(max_length=255, default='*')
automatic = models.BooleanField(default=False)
user = models.CharField(max_length=255, default='*')
user_job_position = models.CharField(max_length=255, default='*')
timestamp = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.recipe.machine.name
My serializer:
class MyCollectSerializer(serializers.ModelSerializer):
class Meta:
model = Collect
fields = [
'justify',
'record',
'user',
'user_job_position',
'timestamp',
'automatic',
'recipe_id',
'general_info',
]
read_only = True
My documents.py:
from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
from mpa.models import Collect
@registry.register_document
class CollectDocument(Document):
general_info = fields.ObjectField(
properties={
'batch': fields.TextField(),
'machine': fields.TextField(),
'recipe_cep': fields.TextField(),
'recipe_mpa': fields.TextField(),
'fabrication_order': fields.TextField(),
}
)
record = fields.NestedField()
def prepare_general_info(self, instance):
return instance.general_info
def prepare_record(self, instance):
return instance.record
class Index:
name = 'collect'
class Django:
model = Collect
fields = [
'justify',
'user',
'user_job_position',
'timestamp',
'automatic',
]
My view:
from dataclasses import fields
from django.http import HttpResponse
from elasticsearch_dsl import Q
from rest_framework.views import APIView
from rest_framework.pagination import LimitOffsetPagination
from mpa.serializers import MyCollectSerializer
from .documents import CollectDocument
from json import JSONEncoder
from rest_framework.renderers import JSONRenderer
from rest_framework.views import APIView
class JSONSearchEncoder(JSONEncoder):
def default(self, obj):
from elasticsearch_dsl import InnerDoc
if isinstance(obj, InnerDoc):
return obj.to_dict()
return super().default(obj)
class JSONSearchRenderer(JSONRenderer):
encoder_class = JSONSearchEncoder
class GeneralSearchAPIView(APIView):
renderer_classes = (JSONSearchRenderer,)
class SearchCollect(GeneralSearchAPIView, LimitOffsetPagination):
collect_serializer = MyCollectSerializer
search_document = CollectDocument
def get(self, request, query):
try:
q = Q(
'multi_match',
query=query,
fields=[
'user',
]
)
search = self.search_document.search().query(q)
response = search.execute()
results = self.paginate_queryset(
response, request, view=self)
serializer = self.collect_serializer(results, many=True)
return self.get_paginated_response(serializer.data)
except Exception as e:
return HttpResponse(e, status=500)
The command 'python manage.py search_index --rebuild' works normally, but when recovering the data I get the following error:
Environment:
Request Method: GET
Request URL: http://localhost:8000/search/GER02
Django Version: 3.2.12
Python Version: 3.9.12
Installed Applications:
['corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_apscheduler',
'mes.apps.MesConfig',
'collector.apps.CollectorConfig',
'vla.apps.VlaConfig',
'mpa.apps.MpaConfig',
'search.apps.SearchConfig',
'authentication',
'crispy_forms',
'rest_framework',
'simple_history',
'tz_detect',
'django_elasticsearch_dsl']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'simple_history.middleware.HistoryRequestMiddleware',
'tz_detect.middleware.TimezoneMiddleware',
'mpa.middlewares.middleware.userLanguageMiddleware',
'mpa.middlewares.middleware.userTimeZoneMiddleware']
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 204, in _get_response
response = response.render()
File "/usr/local/lib/python3.9/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/usr/local/lib/python3.9/site-packages/rest_framework/response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/usr/local/lib/python3.9/site-packages/rest_framework/renderers.py", line 100, in render
ret = json.dumps(
File "/usr/local/lib/python3.9/site-packages/rest_framework/utils/json.py", line 25, in dumps
return json.dumps(*args, **kwargs)
File "/usr/local/lib/python3.9/json/__init__.py", line 234, in dumps
return cls(
File "/usr/local/lib/python3.9/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/lib/python3.9/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/app/search/views.py", line 18, in default
return super().default(obj)
File "/usr/local/lib/python3.9/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
Exception Type: TypeError at /search/GER02
Exception Value: Object of type AttrList is not JSON serializable
What can I do to be able to return the data of this field as a list containing dictionaries?
I appreciate any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论