Jek*_*son 5 python-3.x django-serializer django-rest-framework
我正在处理一个包含大量嵌套信息的 json 文件。为此,UploadElementFromExcelFile(APIView)我在类中使用嵌套循环,在调用serializer.save()方法的最后。然后在ElementCommonInfoSerializer序列化程序中的create()方法中,我保存/更新从序列化程序接收到的数据。此外,我创建/更新一个RfiParticipationStatus模型,该模型仅与最高嵌套级别(使用parent_category变量)相关。但是由于为循环的最底层成员调用了 create 方法,因此我对该RfiParticipationStatus模型进行了大量无用的数据库查询。同样的事情company_information节省。这是来自共享 json 文件的额外信息。它不引用序列化对象,我只需要在 post 方法调用的最开始保存 company_information 一次。在我的代码实现中,根据 for 循环的深度和内容,保存请求会发生数百次。
json数据样本
[
{
"Company_info": [
{
"question": "Company name",
"answer": "Test"
},
{
"question": "Parent company (if applicable)",
"answer": "2test"
},
{....},
{....}
]
},
{
"Parent Category": " rtS2P",
"Category": [
{
"Analytics": [
{
"Data Schema": [
{ '....': "",
"Attachments/Supporting Docs and Location/Link": "tui",
"SM score": 4,
"Analyst notes": "tytyt"
},
{ '....': "",
"Attachments/Supporting Docs and Location/Link": null,
"SM score": null,
"Analyst notes": null
},
]
},
{
"Data Management": [
{
'....': "",
"Attachments/Supporting Docs and Location/Link": null,
"SM score": null,
"Analyst notes": null
},
{....}
]
}
]
},
{
"Configurability": [...]
}
]
},
{
"Parent Category": "DFG",
"Category": [
{
"Contingent Workforce / Services Procurement": [...]
},
{
"Performance Management": [...]
}
]
},
"Parent Category": "...",
.....
]
Run Code Online (Sandbox Code Playgroud)
视图.py
class UploadElementFromExcelFile(APIView):
serializer_class = ElementCommonInfoSerializer
def post(self, request, *args, **kwargs):
context = {'rfiid': kwargs.get('rfiid'), 'vendor': kwargs.get('vendor'), 'analyst': kwargs.get('analyst')}
data = request.data # data is list of dict
company_information = next(iter(data))
context.update(company_information)
try:
with transaction.atomic():
for pc_data in data[1:]: # from dict get PC and Category participate data, exclude firs element - CI
parent_category = pc_data.get('Parent Category')
category_data = pc_data.get('Category')
for data in category_data:
for category, values in data.items(): # Get category name
for subcats in values:
for subcat, element_list in subcats.items(): # Get subcategory name
for num, element in enumerate(element_list, 1): # Get element info
# some logic
data = {......, ......,}
serializer = ElementCommonInfoSerializer(data=data, context=context)
serializer.is_valid(raise_exception=True)
serializer.save()
except ValidationError:
return Response({"errors": (serializer.errors,)},
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(request.data, status=status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)
序列化程序.py
class ElementCommonInfoSerializer(serializers.ModelSerializer):
.....
.....
def create(self, validated_data):
....
# !!!! Question is in the rfi_part_status variable below
rfi_part_status, _ = RfiParticipationStatus.objects.update_or_create(status=pc_status, vendor=vendor, rfi=round,
pc=parent_category.first(),
defaults={'last_vendor_response': lvr, 'last_analyst_response': lar})
# And question else in company_information save
company_information = self.context.get('Company_info')
for ci in company_information:
ciq, _ = CompanyGeneralInfoQuestion.objects.get_or_create(question=ci.get('question'), rfi=round)
cia, _ = CompanyGeneralInfoAnswers.objects.get_or_create(vendor=vendor, question=ciq,
answer=ci.get('answer'))
#another crete logic
.....
.....
return self
Run Code Online (Sandbox Code Playgroud)
问题是如何rfi_part_status仅在通过嵌套循环 ( for pc_data in data[1:]:)的最上层元素时才调用对象的创建。和同样的情况company information
UPD(根据Linovia问题)!! 模型.py
class RfiParticipationStatus(models.Model):
status = models.CharField(max_length=50, choices=STATUS_NAME)
vendor = models.ForeignKey('Vendors', models.DO_NOTHING, related_name='to_vendor_status')
rfi = models.ForeignKey('Rfis', models.DO_NOTHING, related_name='to_rfis_status')
pc = models.ForeignKey(ParentCategories, models.DO_NOTHING, blank=True, null=True)
last_vendor_response = models.IntegerField(blank=True, null=True)
last_analyst_response = models.IntegerField(blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)
RfiParticipationStatus创建对象时pc,仅从序列化器数据中获取(父类别)值。所有其他值均在此过程中计算。
| 归档时间: |
|
| 查看次数: |
115 次 |
| 最近记录: |