我正在使用Django Rest框架为现有(遗留)SQL数据库构建一个readapi。问题是这样会产生太多的查询。你知道吗
我想选择一个Widget
及其(大约40个)相关的小部件,包括每个相关小部件的widget_technology
。小部件的技术取决于某个标记的存在与否(我知道这是次优的数据库设计,但它是遗留的……)。问题是这会导致40多个查询(每个相关小部件一个)。你知道吗
有什么办法解决吗?你知道吗
我一直在看代码中DRF部分的prefetch_related('widget_tags')
,但这似乎没有帮助。你知道吗
这是主表:
class Widgets(models.Model):
widget_id = models.AutoField(primary_key=True)
widget_slug = models.CharField(unique=True, max_length=70)
widget_name = models.CharField(max_length=70)
widget_tags = models.ManyToManyField('Tags', through='IsTag')
related_widgets = models.ManyToManyField('Widgets', through='Similar', related_name='similar')
@property
def widget_technology(self):
if self.widget_tags.filter(tag_slug='tech_1').exists():
return 'TECH_1'
elif self.widget_tags.filter(tag_slug='tech_2').exists():
return 'TECH_2'
class Meta:
managed = False
db_table = 'widgets'
为完整起见,以下是其他表格:
class Similar(models.Model):
first_widget = models.ForeignKey(
Widgets, models.DO_NOTHING, primary_key=True, related_name='similar_first_widget'
)
second_widget = models.ForeignKey(
Widgets, models.DO_NOTHING, related_name='similar_second_widget'
)
score = models.IntegerField()
class Meta:
managed = False
db_table = 'similar'
unique_together = (('first_widget', 'second_widget'),)
class IsTag(models.Model):
is_tag_widget = models.ForeignKey(Widgets, models.DO_NOTHING, primary_key=True)
is_tag_tag = models.ForeignKey('Tags', models.DO_NOTHING)
class Meta:
managed = False
db_table = 'is_tag'
unique_together = (('is_tag_widget', 'is_tag_tag'),)
class Tags(models.Model):
tag_id = models.AutoField(primary_key=True)
tag_slug = models.CharField(max_length=100)
class Meta:
managed = False
db_table = 'tags'
编辑:添加视图
class WidgetDetail(APIView):
def get_object(self, slug):
try:
return Widgets.objects.get(widget_slug=slug)
# tried this but didn't solve the issue:
# return Widgets.objects.prefetch_related('related_widgets', 'related_widgets__widget_tags').get(widget_slug=slug)
except Widgets.DoesNotExist:
raise Http404
def get(self, request, slug, format=None):
widget = self.get_object(slug)
serializer = FullWidgetSerializer(widget)
return Response(serializer.data)
以及序列化程序:
class FullWidgetSerializer(serializers.ModelSerializer):
# special cases
widget_tags = SimpleTagSerializer(many=True, read_only=True)
related_widgets = SimpleWidgetSerializer(many=True, read_only=True)
class Meta:
model = Widgets
fields = (
'widget_slug', 'related_widgets', 'widget_tags', 'widget_technology')
class SimpleWidgetSerializer(serializers.ModelSerializer):
class Meta:
model = Widgets
fields = ('widget_slug', 'widget_technology')
目前没有回答
相关问题 更多 >
编程相关推荐