我是Django的新手,但在我们的项目中我们有一个Django后端,没有其他人愿意接触它,所以我不得不对此进行一些调整。模型设置,一切正常,但我们需要一个新视图,我们需要有关我们的一个模型的基本数据,没有引用模型(只需要外键ID)。我之前已经有了SO的解决方案,但是当该解决方案返回首选结果时,仍然会在后台执行大量查询。每个返回的对象都会查询每个引用的对象,同时我们只需要它们的id /键。
与此同时,我已将序列化器修改为trinchet,但这并没有帮助。仍然有很多疑问。
型号:
class Row(models.Model):
row = models.IntegerField(null=True, blank=True)
height = models.TextField(null=True, blank=True)
key = models.CharField(max_length=36, unique = True)
def save(self, *args, **kwargs):
super(Row, self).save(*args, **kwargs)
class Column(models.Model):
col = models.IntegerField(null=True, blank=True)
width = models.TextField(null=True, blank=True)
key = models.CharField(max_length=36, unique = True)
def save(self, *args, **kwargs):
super(Column, self).save(*args, **kwargs)
class Product(models.Model):
key = models.CharField(max_length=36, unique = True)
text = models.TextField(null=True, blank=True)
column = models.ForeignKey(Column, db_column='column_key', to_field='key', related_name="products")
row = models.ForeignKey(Row, db_column='row_key', to_field='key', related_name="products")
merged_with = models.ForeignKey("Product", db_column='merged_with_key', to_field='key', related_name="merges", blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
updated_by = models.ForeignKey('auth.User', null=True)
串行:
class SimpleProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('id', 'key', 'text', 'row', 'column', 'merged_with')
row = serializers.PrimaryKeyRelatedField(read_only = True)
column = serializers.PrimaryKeyRelatedField(read_only = True)
merged_with = serializers.PrimaryKeyRelatedField(read_only = True)
结果是一个简单的json,它包含纯产品对象数组:
[{
id: 1,
key: "1746495d-8ea0-42df-9ed9-06df621ef7c5",
column_key: "<key of refrenced column>"
key: "1746495d-8ea0-42df-9ed9-06df621ef7c5"
merged_with_key: "<key of refrenced product>"
row_key: "<key of refrenced row>"
text: "sometext"
}, .....]
但是在后端,已经执行了大量查询来检索每个产品对象的列/行。
DEBUG 2017-03-18 11:27:27,704 utils 424 140142129104640 (0.001) SELECT "dashboard_product"."id", "dashboard_product"."dashboard_id", "dashboard_product".
"key", "dashboard_product"."text", "dashboard_product"."column_key", "dashboard_produc
t"."row_key", "dashboard_product"."merged_with_key" FROM "dashboard_product" WHERE "dashboard_product"."key" IN ('2a578e00-af19-4b3d-a
65f-5bf9daf490f7', '29c571bc-fb58-42b6-8721-edb8a96cc682', '6fb9ed7a-0e4f-4c06-95d3-15f16d281247', 'b6aa4aa3-be47-4641-a79b-1eddc3e4d28d', '026ea99a-75cd
-4708-adbd-117aef19a159', '86f49c57-1ba4-4b63-aadb-01eb95984306', 'f4a2f175-afa2-4337-891a-fce15ceaab1b', 'c31f2244-3e44-4c7e-b68a-997a0c25426f', 'cb2656
c3-7515-443a-8217-45e8a4e32d42', NULL, 'a801e609-49a2-46bb-9fad-453e9ebc6143', '2e2c85ae-bd60-43ae-9b6c-00988e69d470', '54165d95-ced7-4e28-b6e8-6c604f094
808', '74bda05f-5bf3-47ec-bbb0-b16eaf1839ec'); args=('2a578e00-af19-4b3d-a65f-5bf9daf490f7', '29c571bc-fb58-42b6-8721-edb8a96cc682', '6fb9ed7a-0e4f-4c06-
95d3-15f16d281247', 'b6aa4aa3-be47-4641-a79b-1eddc3e4d28d', '026ea99a-75cd-4708-adbd-117aef19a159', '86f49c57-1ba4-4b63-aadb-01eb95984306', 'f4a2f175-afa
2-4337-891a-fce15ceaab1b', 'c31f2244-3e44-4c7e-b68a-997a0c25426f', 'cb2656c3-7515-443a-8217-45e8a4e32d42', None, 'a801e609-49a2-46bb-9fad-453e9ebc6143',
'2e2c85ae-bd60-43ae-9b6c-00988e69d470', '54165d95-ced7-4e28-b6e8-6c604f094808', '74bda05f-5bf3-47ec-bbb0-b16eaf1839ec')
DEBUG 2017-03-18 11:27:27,712 utils 424 140142129104640 (0.001) SELECT "dashboard_row"."id", "dashboard_row"."dashboard_id", "dashboard_row"."row", "dash
board_row"."height", "dashboard_row"."key" FROM "dashboard_row" WHERE "dashboard_row"."key" = '905bd277-3a31-4361-8877-dc3c019aff29'; args=('905bd277-3a3
1-4361-8877-dc3c019aff29',)
DEBUG 2017-03-18 11:27:27,717 utils 424 140142129104640 (0.001) SELECT "dashboard_column"."id", "dashboard_column"."dashboard_id", "dashboard_column"."co
l", "dashboard_column"."width", "dashboard_column"."key" FROM "dashboard_column" WHERE "dashboard_column"."key" = '4633a6a0-4532-4681-851e-562c1e409b15';
args=('4633a6a0-4532-4681-851e-562c1e409b15',)
DEBUG 2017-03-18 11:27:27,720 utils 424 140142129104640 (0.000) SELECT "dashboard_row"."id", "dashboard_row"."dashboard_id", "dashboard_row"."row", "dash
board_row"."height", "dashboard_row"."key" FROM "dashboard_row" WHERE "dashboard_row"."key" = '905bd277-3a31-4361-8877-dc3c019aff29'; args=('905bd277-3a3
1-4361-8877-dc3c019aff29',)
DEBUG 2017-03-18 11:27:27,722 utils 424 140142129104640 (0.000) SELECT "dashboard_column"."id", "dashboard_column"."dashboard_id", "dashboard_column"."co
l", "dashboard_column"."width", "dashboard_column"."key" FROM "dashboard_column" WHERE "dashboard_column"."key" = 'e30ea177-3819-4b57-b725-6d89b207d740';
args=('e30ea177-3819-4b57-b725-6d89b207d740',)
DEBUG 2017-03-18 11:27:27,724 utils 424 140142129104640 (0.000) SELECT "dashboard_row"."id", "dashboard_row"."dashboard_id", "dashboard_row"."row", "dash
board_row"."height", "dashboard_row"."key" FROM "dashboard_row" WHERE "dashboard_row"."key" = '6a5a9e1a-9098-430a-985a-81c61e29f3db'; args=('6a5a9e1a-909
8-430a-985a-81c61e29f3db',)
... etc
如何阻止此行为,仅执行一个返回产品对象的查询,并且不会触及我们不使用的引用。现在这是一个严重的性能瓶颈,我花了很长时间才找到解决方案。 我已经使用json序列化器解决了这个问题,但它们无法处理数组字段,还有一些其他问题。必须有一种更优雅的方式来解决这个问题。
BR,
乔鲍
答案 0 :(得分:0)
你可以做几件事:
SimpleProductSerializer
序列化程序中为每个ForeignKey定义PrimaryKeyRelatedField字段,或SimpleProductSerializer
。select_related/prefetch_related
醇>
它们都将消除不需要的查询,但在第二种情况下,您将获得一些您不需要的数据(在查询中)(整个相关对象而不仅仅是ID)